KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sourceforge > chart2d > Area


1 /**
2  * Chart2D, a java library for drawing two dimensional charts.
3  * Copyright (C) 2001 Jason J. Simas
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * The author of this library may be contacted at:
19  * E-mail: jjsimas@users.sourceforge.net
20  * Street Address: J J Simas, 887 Tico Road, Ojai, CA 93023-3555 USA
21  */

22
23
24 package net.sourceforge.chart2d;
25
26
27 import javax.swing.*;
28 import java.awt.*;
29 import java.util.*;
30
31
32 /**
33  * An Advanced Bordered Area. Allows auto and manual resizing and
34  * auto and manual positioning. Contains many public static variables for use
35  * when extending this class.
36  * <p><b>Basic Sizing and Colors:</b><br>
37  * The typical bordered area class will simply paint a border of a specified
38  * thickness within an area, where the inner edges of the area touch the outer
39  * edges of the border. This class can do much more. Each border can be set
40  * to a different thickness and color. This introduces the problem of handling
41  * the corners of the borders. If the left border has color green, and the top
42  * border has color red, which color is the top left corner? Each corner can
43  * be associated with any adjacent border.
44  * <p><b>Inner Space And Gaps:</b><br>
45  * Sometimes, some space between the thing bordered and the border is desired.
46  * That is, if bordering some text, then having some space between the
47  * text and the border may be desirable. The thickness of the gap between the
48  * the left, right, top, and bottom borders may each be individually set.
49  * The location and size of this inner space may be obtained directly.
50  * <p><b>Resizing And Growing Borders And Gaps:</b><br>
51  * The borders and gaps can automatically grow when the size is changed. In
52  * order to maintain the look of zooming in on something, the borders and gaps
53  * can grow with the resizing of the area. For example, if the area grows in
54  * the horizontal direction, then the left and right borders and gaps will
55  * grow respective of the amount of change in the area width, depending
56  * on this classes settings. If keeping any of the borders equal to any of the
57  * others is desireable, such as a "grow only when all grow" policy, then
58  * any border may be associated with any other border. The sizes of the
59  * associated borders will be equal to the least of them.
60  * <p><b>More Basics:</b><br>
61  * This area can have a background color, or no background at all. And
62  * each border and gap can be set to not exist, individually.
63  * <p><b>Locating: Automatically and Manually:</b><br>
64  * Sometimes the size of component to be bordered cannot be known until after
65  * the borders and gaps have been calculated (relevant when using growing
66  * borders and gaps). This class allows the available space, after subtracting
67  * borders and gaps, to obtained. The size of the component to be bordered can
68  * then be calculated, making sure it fits within this space. The size of the
69  * component can be passed to this class, this class will place the gaps and
70  * borderes around the component for a (near) perfect fit. This means that
71  * where to place this bordered area within the maximum area is an open
72  * question. This class allows options of automatic centering (both
73  * horizontally and vertically, justifying to the left, right, top, and/or
74  * bottom edges of the maximum area, and doing nothing such that the area can
75  * be manually set, and any combination thereof.
76  * <p><b>Examples:</b><br>
77  * <ul>
78  * <li>No Growing And Border Encloses Maximum Area:<br>
79  * <code>setAutoSizes (true, true);</code>
80  * <li>Growing And Border Encloses Maximum Area:<br>
81  * <code>setAutoSizes (false, true);</code>
82  * <li>No Growing, Border Encloses Minimum Area, And Centered:<br>
83  * <code>setAutoSizes (true, false);<br>
84  * setAutoJustifys (true, true);<br>
85  * setJustifications (CENTER, CENTER);</code>
86  * <li>Growing, Border Encloses Minimum Area, And Manually Located:<br>
87  * <code>setAutoSizes (false, false);<br>
88  * setAutoJustifys (false, false);</code>
89  * </ul>
90  * <p><b>Details Of Growing:</b><br>
91  * Growing is based on "model" sizes. By default, everything has a
92  * model size (the area, the borders, and the gaps). The defaults
93  * currently are the first maximum size setting for the area,
94  * 2 (for all borders), and 2 (for all gaps). Growing
95  * is accomplished by dividing the maximum area size by the model area size
96  * and applying this ratio the border and gap thicknesses.
97  * If growing in the horizontal direction, the width sizes are used. If
98  * growing in the vertical direction, the height sizes are used. If growing
99  * in both directions, then both are calculated and the lesser is used.
100  * However, all of these values can be changed. Ideally, one would set
101  * the model area size to your normal viewing size, and all of the
102  * inner components model sizes (borders and thicknesses) to the best sizes
103  * at this model area size. However, just setting the model area size to the
104  * normal viewing size of the area most likely will be sufficient. Generally,
105  * the initial size is the normal size, do set the model size to the initial
106  * size, use the resetAreaModel method before setting the maximum size. When
107  * you set the maximum size, the area model size will automatically reset
108  * itself to this size.
109  * <p><b>Notes:</b><br>
110  * <ul>
111  * <li>This class assumes no null values. Pass zero based values intead. For
112  * example, <code>new Point()</code> instead of <code>null</code>.
113  * <li>Both Growing and shrinking are supported, and are the same. When
114  * is written, in these comments, gowing and shrinking is meant.
115  * </ul>
116  */

117  class Area {
118
119
120   /**
121    * Indicates the maximum.
122    */

123   static final int MAX = 0;
124   /**
125    * Indicates the model or maximum model.
126    */

127   static final int MAXMODEL = 1;
128   /**
129    * Indicates the minimum.
130    */

131   static final int MIN = 2;
132   /**
133    * Indicates the width.
134    */

135   static final int WIDTH = 0;
136   /**
137    * Indicates the height.
138    */

139   static final int HEIGHT = 1;
140   /**
141    * Indicates the lesser.
142    */

143   static final int LESSER = 2;
144   /**
145    * Indicates the left.
146    */

147   static final int LEFT = 0;
148   /**
149    * Indicates the right.
150    */

151   static final int RIGHT = 1;
152   /**
153    * Indicates the top.
154    */

155   static final int TOP = 2;
156   /**
157    * Indicates the bottom.
158    */

159   static final int BOTTOM = 3;
160   /**
161    * Indicates the center.
162    */

163   static final int CENTER = 4;
164   /**
165    * Indicates the left right.
166    */

167   static final int LEFTRIGHT = 0;
168   /**
169    * Indicates the left top.
170    */

171   static final int LEFTTOP = 1;
172   /**
173    * Indicates the right bottom.
174    */

175   static final int LEFTBOTTOM = 2;
176   /**
177    * Indicates the right top.
178    */

179   static final int RIGHTTOP = 3;
180   /**
181    * Indicates the right bottom.
182    */

183   static final int RIGHTBOTTOM = 4;
184   /**
185    * Indicates the top bottom.
186    */

187   static final int TOPBOTTOM = 5;
188   /**
189    * Indicates the horizontal.
190    */

191   static final int HORIZONTAL = 0;
192   /**
193    * Indicates the vertical.
194    */

195   static final int VERTICAL = 1;
196   /**
197    * Indicates the centered.
198    */

199   static final int CENTERED = 0;
200   /**
201    * Indicates the betweem.
202    */

203   static final int BETWEEN = 1;
204   /**
205    * Indicates the labels bottom.
206    */

207   static final int LABELSBOTTOM = 0;
208   /**
209    * Indicates the labels left.
210    */

211   static final int LABELSLEFT = 1;
212   /**
213    * Indicates the continuous.
214    */

215   static float[] CONTINUOUS = {10.0f, 0.0f};
216   /**
217    * Indicates the dashed.
218    */

219   static float[] DASHED = {7.0f, 3.0f};
220   /**
221    * Indicates the dotted.
222    */

223   static float[] DOTTED = {3.0f, 3.0f};
224   /**
225    * Indicates none.
226    */

227   static int NONE = 6;
228
229
230   private Point[] sizeLocations;
231   private Dimension[] sizes;
232   private boolean[] autoSizes;
233
234   private Point[] spaceSizeLocations;
235   private Dimension[] spaceSizes;
236   private boolean[] autoJustifys;
237   private int[] justifications;
238
239   private boolean backgroundExistence;
240   private Rectangle background;
241   private Color backgroundColor;
242
243   private float[] ratios;
244   private boolean[] customizeRatios;
245
246   private boolean[] borderExistences;
247   private Rectangle[] borders;
248   private int[] borderThicknessModels;
249   private int[] borderThicknesses;
250   private int[] borderCornerAssociations;
251   private boolean[] borderAssociations;
252   private Color[] borderColors;
253
254   private boolean[] gapExistences;
255   private int[] gapThicknessModels;
256   private int[] gapThicknesses;
257   private boolean[] gapAssociations;
258
259   private boolean lockRatios;
260   private int lightSource;
261   private Paint backgroundPaint;
262
263   private boolean resetAreaModel;
264   private boolean unsetAreaModelOnUpdate;
265   private boolean needsUpdate;
266
267
268   /**
269    * Creates a new Area.
270    */

271   Area() {
272
273     createObjects();
274
275     setAutoSizes (true, true);
276     setAutoJustifys (true, true);
277     setJustifications (CENTER, CENTER);
278
279     setBackgroundExistence (true);
280     setBackgroundColor (Color.white);
281
282     setBorderExistences (true, true, true, true);
283     setBorderThicknessModels (2, 2, 2, 2);
284     setBorderAssociations (true, true, true, true, true, true);
285     setBorderCornerAssociations (LEFT, BOTTOM, TOP, RIGHT);
286     setBorderColors (Color.black, Color.black, Color.black, Color.black);
287
288     setGapExistences (true, true, true, true);
289     setGapThicknessModels (5, 5, 5, 5);
290
291     setLockRatios (true);
292     setCustomRatio (WIDTH, false, 0f);
293     setCustomRatio (HEIGHT, false, 0f);
294     setCustomRatio (LESSER, false, 0f);
295
296     setLightSource (NONE);
297
298     resetAreaModel (true);
299
300     unsetAreaModelOnUpdate = false;
301     needsUpdate = true;
302   }
303
304
305   /**
306    * Sets the source of light for gradient paint of the background.
307    * Possible values for the source parameter are: LEFT, RIGHT, TOP, BOTTOM, and NONE.
308    * @param source Which side the light is coming from.
309    */

310   void setLightSource (int source) {
311     lightSource = source;
312     needsUpdate = true;
313   }
314
315
316   /**
317    * Sets the location of a size/area.
318    * @param which Which area to relocate. MAX is the only possible accepted
319    * value.
320    * @param location The new point of the top left of the area. The outer
321    * edges of the left and top borders will touch this. Must not be null.
322    */

323   final void setSizeLocation (int which, Point location) {
324
325     needsUpdate = true;
326     sizeLocations[MAX] = location;
327   }
328
329
330   /**
331    * Sets the location of an internal space area of a size area.
332    * @param which Which space area to relocate. MIN is the only possible
333    * value. If horizontal justification is true, then the x value will be
334    * ignored. If vertical justification is true, then the y value will be
335    * ignored.
336    * @param location The new point of the top left of the space area. The
337    * inner edges of the top and left gaps will touch this. Must not be null.
338    */

339   final void setSpaceSizeLocation (int which, Point location) {
340
341     needsUpdate = true;
342     int x = autoJustifys[HORIZONTAL] ? spaceSizeLocations[MIN].x : location.x;
343     int y = autoJustifys[VERTICAL] ? spaceSizeLocations[MIN].y : location.y;
344     spaceSizeLocations[MIN] = new Point (x, y);
345   }
346
347
348   /**
349    * Adjusts settings to enable/disable auto justification of a minimum area
350    * that is less than a maximum area.
351    * @param horizontal If true, then horizontal justification is
352    * enabled.
353    * @param vertical If true, then vertical justification is enabled.
354    */

355   final void setAutoJustifys (boolean horizontal, boolean vertical) {
356
357     needsUpdate = true;
358     autoJustifys[HORIZONTAL] = horizontal;
359     autoJustifys[VERTICAL] = vertical;
360   }
361
362
363   /**
364    * Adjusts the actual justifications of minimum areas that are less than
365    * maximum areas. Justifications effect the locations of minimum areas.
366    * Either are only respected when their auto justification is enabled.
367    * For example, if horizontal justify is center, then the minimum area will
368    * be horizontally centered within the maximum area.
369    * @param horizontal Sets the horizontal justification for the minimum
370    * area. Possible values are LEFT, RIGHT and CENTER.
371    * @param vertical Sets the vertical justification for the minimum
372    * area. Possible values are LEFT, RIGHT and CENTER.
373    */

374   final void setJustifications (int horizontal, int vertical) {
375
376     needsUpdate = true;
377     justifications[HORIZONTAL] = horizontal;
378     justifications[VERTICAL] = vertical;
379   }
380
381
382   /**
383    * Adjusts the settings that allow automatic (or default) sizing. Both are
384    * on the maximum size which is required, and must be set to be useful.
385    * @param maxModel If true, then the maximum model size will always
386    * be equal to the maximum size. This disables growing because it keeps the
387    * resizing ratios at 1. If false, then maximum model is constant; so if the
388    * maximum size changes then the ratios will adjust accordingly.
389    * @param min If true, then the minimum size will be kept equal to
390    * the maximum size. This means that the borders' outer edges will touch
391    * the maximum size.
392    */

393   final void setAutoSizes (boolean maxModel, boolean min) {
394
395     needsUpdate = true;
396     autoSizes[MAXMODEL] = maxModel;
397     autoSizes[MIN] = min;
398   }
399
400
401   /**
402    * Makes such that the widh and the heighh ratios are the same as the
403    * lesser ratio. If you want components to grow only if all of them grow,
404    * then lock ratios, true, will cause this.
405    * @param lock True causes all the ratios to equal the lesser ratio.
406    */

407   final void setLockRatios (boolean lock) {
408
409     lockRatios = lock;
410   }
411
412
413   /**
414    * Specifies whether to customize a particular ratio, overriding the
415    * calculation of it.
416    * @param which Which ratio to customize.
417    * @param customize Whether to customize the ratio.
418    * @param ratio The custom ratio.
419    */

420   final void setCustomRatio (int which, boolean customize, float ratio) {
421
422     needsUpdate = true;
423     customizeRatios[which] = customize;
424     ratios[which] = ratio;
425   }
426
427
428
429   /**
430    * Sets the sizes of the areas. If setting the maximum size and if
431    * resetAreaModel was called previously, then the maximum model size will
432    * be made equal to the maximum size; this ensures that all the default sizes
433    * of borders and gaps will be used at this maximum size; at this maximum size
434    * the resizing ratio will be 1.
435    * @param which Which size to change. Possible values are MAX and
436    * MAXMODEL.
437    * @param size The new size. Must not be null.
438    */

439   final void setSize (int which, Dimension size) {
440
441     needsUpdate = true;
442     sizes[which] = size;
443     if (resetAreaModel && !unsetAreaModelOnUpdate && which == MAX) {
444       unsetAreaModelOnUpdate = true;
445       sizes[MAXMODEL] = size;
446     }
447   }
448
449
450   /**
451    * Sets the size of the space; that is the area less the borders and gaps.
452    * @param which Which space size to change. Possible values are MIN.
453    * @param size The new size. Must not be null.
454    */

455   final void setSpaceSize (int which, Dimension size) {
456
457     needsUpdate = true;
458     spaceSizes[which] = size;
459   }
460
461
462   /**
463    * Adjusts whether there exists a background or not.
464    * @param existence If true, then there is.
465    */

466   final void setBackgroundExistence (boolean existence) {
467
468     needsUpdate = true;
469     backgroundExistence = existence;
470   }
471
472
473   /**
474    * Adjusts the color of the background. Doesn't change the background's
475    * existence.
476    * @param color The color of the background.
477    */

478   final void setBackgroundColor (Color color) {
479
480     needsUpdate = true;
481     backgroundColor = color;
482   }
483
484
485   /**
486    * Adjusts whether there exists borders, each individually. If a border does
487    * not exist, then its is not used in calculations or in painting.
488    * @param left If true, then the left border does exist.
489    * @param right If true, then the right border does exist.
490    * @param top If true, then the top border does exist.
491    * @param bottom If true, then the bottom border does exist.
492    */

493   final void setBorderExistences
494     (boolean left, boolean right, boolean top, boolean bottom) {
495
496     needsUpdate = true;
497     borderExistences[LEFT] = left;
498     borderExistences[RIGHT] = right;
499     borderExistences[TOP] = top;
500     borderExistences[BOTTOM] = bottom;
501   }
502
503
504   /**
505    * Adjusts whether there exists borders. If borders do
506    * not exist, then they are not used in calculations or in painting.
507    * @param existences If true, then the borders do not exist.
508    */

509   final void setBorderExistence (boolean existences) {
510
511     needsUpdate = true;
512     borderExistences[LEFT] = existences;
513     borderExistences[RIGHT] = existences;
514     borderExistences[TOP] = existences;
515     borderExistences[BOTTOM] = existences;
516   }
517
518
519   /**
520    * Adjusts the thickness of the border models. These values will be
521    * applied to a ratio to determine their final thicknesses. The ratio is the
522    * maximum size divided by the maximum model size. More information is in the
523    * introductory notes for this class.
524    * @param left The model thickness for the left border.
525    * @param right The model thickness for the right border.
526    * @param top The model thickness for the top border.
527    * @param bottom The model thickness for the bottom border.
528    */

529   final void setBorderThicknessModels
530     (int left, int right, int top, int bottom) {
531
532     needsUpdate = true;
533     borderThicknessModels[LEFT] = left;
534     borderThicknessModels[RIGHT] = right;
535     borderThicknessModels[TOP] = top;
536     borderThicknessModels[BOTTOM] = bottom;
537   }
538
539
540   /**
541    * Adjusts the thickness of the border models. These values will be
542    * applied to a ratio to determine their final thicknesses. The ratio is the
543    * maximum size divided by the maximum model size. More information is in the
544    * introductory notes for this class.
545    * @param thickness The model thickness for the border.
546    */

547   final void setBorderThicknessModel (int thickness) {
548
549     needsUpdate = true;
550     borderThicknessModels[LEFT] = thickness;
551     borderThicknessModels[RIGHT] = thickness;
552     borderThicknessModels[TOP] = thickness;
553     borderThicknessModels[BOTTOM] = thickness;
554   }
555
556
557   /**
558    * Associates each corner with one border. The corner will take on the same
559    * color as the border associated with it.
560    * @param leftTop The border to associate with the leftTop corner.
561    * Possible values are LEFT and TOP.
562    * @param rightTop The border to associate with the rightTop corner.
563    * Possible values are RIGHT and TOP.
564    * @param leftBottomThe border to associate with the leftBottom corner.
565    * Possible values are LEFT and BOTTOM.
566    * @param rightBottom The border to associate with the rightBottom corner.
567    * Possible values are RIGHT and BOTTOM.
568    */

569   final void setBorderCornerAssociations
570     (int leftTop, int leftBottom, int rightTop, int rightBottom) {
571
572     needsUpdate = true;
573       borderCornerAssociations[LEFTTOP] = leftTop;
574       borderCornerAssociations[RIGHTTOP] = rightTop;
575       borderCornerAssociations[LEFTBOTTOM] = leftBottom;
576       borderCornerAssociations[RIGHTBOTTOM] = rightBottom;
577   }
578
579
580   /**
581    * Associates border thicknesses with other border thicknesses. Each possible
582    * association between the four borders can be represented by setting six
583    * booleans. When a border is associated with another border, then their
584    * thickness is equal to the lesser thickness between the two.
585    * @param leftRight If true, then associates the left and right
586    * borders.
587    * @param leftTop If true, then associates the left and top borders.
588    * @param leftBottom If true, then associates the left and bottom
589    * borders.
590    * @param rightTop If true, then associates the right and top borders.
591    * @param rightBottom If true, then associates the right and bottom
592    * borders.
593    * @param topBottom If true, then associates the top and bottom
594    * borders.
595    */

596   final void setBorderAssociations
597     (boolean leftRight, boolean leftTop, boolean leftBottom,
598     boolean rightTop, boolean rightBottom, boolean topBottom) {
599
600     needsUpdate = true;
601     borderAssociations[LEFTRIGHT] = leftRight;
602     borderAssociations[LEFTTOP] = leftTop;
603     borderAssociations[LEFTBOTTOM] = leftBottom;
604     borderAssociations[RIGHTTOP] = rightTop;
605     borderAssociations[RIGHTBOTTOM] = rightBottom;
606     borderAssociations[TOPBOTTOM] = topBottom;
607   }
608
609
610   /**
611    * Sets the color of each border, individually.
612    * @param left The color of the left border.
613    * @param right The color of the right border.
614    * @param top The color of the top border.
615    * @param bottom The color of the bottom border.
616    */

617   final void setBorderColors
618     (Color left, Color right, Color top, Color bottom) {
619
620     needsUpdate = true;
621     borderColors[LEFT] = left;
622     borderColors[RIGHT] = right;
623     borderColors[TOP] = top;
624     borderColors[BOTTOM] = bottom;
625   }
626
627
628
629   /**
630    * Sets the color of the border (each border).
631    * @param color The color of the border.
632    */

633   final void setBorderColor (Color color) {
634
635     needsUpdate = true;
636     borderColors[LEFT] = color;
637     borderColors[RIGHT] = color;
638     borderColors[TOP] = color;
639     borderColors[BOTTOM] = color;
640   }
641
642
643
644   /**
645    * Adjusts whether there exists gaps, each individually. If a gap does
646    * not exist, then its is not used in calculations.
647    * @param left If true, then the left gap does exist.
648    * @param right If true, then the right gap does exist.
649    * @param top If true, then the top gap does exist.
650    * @param bottom If true, then the bottom gap does exist.
651    */

652   final void setGapExistences
653     (boolean left, boolean right, boolean top, boolean bottom) {
654
655     needsUpdate = true;
656     gapExistences[LEFT] = left;
657     gapExistences[RIGHT] = right;
658     gapExistences[TOP] = top;
659     gapExistences[BOTTOM] = bottom;
660   }
661
662
663   /**
664    * Adjusts whether there exists gaps. If a gap does
665    * not exist, then its is not used in calculations.
666    * This is equivalent to calling
667    * setGapExistences (boolean, boolean, boolean, boolean).
668    * @param existence If true, then the gap exists.
669    */

670   final void setGapExistence(boolean existence) {
671
672     setGapExistences (existence, existence, existence, existence);
673   }
674
675
676   /**
677    * Adjusts the thickness of the gap models. These values will be
678    * applied to a ratio to determine their final thicknesses. The ratio is the
679    * maximum size divided by the maximum model size. More information is in the
680    * introductory notes for this class.
681    * @param left The model thickness for the left gap.
682    * @param right The model thickness for the right gap.
683    * @param top The model thickness for the top gap.
684    * @param bottom The model thickness for the bottom gap.
685    */

686   final void setGapThicknessModels (int left, int right, int top, int bottom) {
687
688     needsUpdate = true;
689     gapThicknessModels[LEFT] = left;
690     gapThicknessModels[RIGHT] = right;
691     gapThicknessModels[TOP] = top;
692     gapThicknessModels[BOTTOM] = bottom;
693   }
694
695
696   /**
697    * Adjusts the thickness of the gap models. These values will be
698    * applied to a ratio to determine their final thicknesses. The ratio is the
699    * maximum size divided by the maximum model size. More information is in the
700    * introductory notes for this class.
701    * @param thickness The model thickness for the gap.
702    */

703   final void setGapThicknessModel (int thickness) {
704
705     needsUpdate = true;
706     gapThicknessModels[LEFT] = thickness;
707     gapThicknessModels[RIGHT] = thickness;
708     gapThicknessModels[TOP] = thickness;
709     gapThicknessModels[BOTTOM] = thickness;
710   }
711
712
713   /**
714    * Associates gap thicknesses with other gap thicknesses. Each possible
715    * association between the four gaps can be represented by setting six
716    * booleans. When a gap is associated with another gap, then their
717    * thickness is equal to the lesser thickness between the two.
718    * @param leftRight If true, then associates the left and right gaps.
719    * @param leftTop If true, then associates the left and top gaps.
720    * @param leftBottom If true, then associates the left and bottom
721    * gaps.
722    * @param rightTop If true, then associates the right and top gaps.
723    * @param rightBottom If true, then associates the right and bottom
724    * gaps.
725    * @param topBottom If true, then associates the top and bottom gaps.
726    */

727   final void setGapAssociations
728     (boolean leftRight, boolean leftTop, boolean leftBottom,
729     boolean rightTop, boolean rightBottom, boolean topBottom) {
730
731     needsUpdate = true;
732     gapAssociations[LEFTRIGHT] = leftRight;
733     gapAssociations[LEFTTOP] = leftTop;
734     gapAssociations[LEFTBOTTOM] = leftBottom;
735     gapAssociations[RIGHTTOP] = rightTop;
736     gapAssociations[RIGHTBOTTOM] = rightBottom;
737     gapAssociations[TOPBOTTOM] = topBottom;
738   }
739
740
741   /**
742    * Gets the source of light for gradient paint of the background.
743    * Possible values for the source parameter are: LEFT, RIGHT, TOP, BOTTOM, and NONE.
744    * @return Which side the light is coming from.
745    */

746   int getLightSource() {
747     return lightSource;
748   }
749
750
751   /**
752    * Returns the space area location. The space area is the area within the
753    * bordered area. It is the area (max or min) less borderss and gaps.
754    * Updates everything before returning the value.
755    * @param which Which space area location to return. Posible values are MAX
756    * and MIN.
757    * @return The location of the space area.
758    */

759   final Point getSpaceSizeLocation (int which) {
760
761     updateArea();
762     return spaceSizeLocations[which];
763   }
764
765
766   /**
767    * Returns the auto sizing properties. Both the max model area size and the
768    * min area size can be auto sized. Autosizing is based on the max area size.
769    * If autosizing, then the area is equal to the max area size.
770    * @param which Which auto size property to return. Possible values are
771    * MAXMODEL and MIN.
772    * @return True, if this area is auto sizing.
773    */

774   final boolean getAutoSize (int which) {
775
776     return autoSizes[which];
777   }
778
779
780   /**
781    * Returns the size of the area. The area size is the dimension enclosing the
782    * border.
783    * Updates everything before returning the value.
784    * @param which Which size to return. Possible values are MAX, MAXMODEL, and
785    * MIN.
786    * @return The size of the area.
787    */

788   final Dimension getSize (int which) {
789
790     updateArea();
791     return sizes[which];
792   }
793
794
795   /**
796    * Returns the location of the area. The location is the top left corner of
797    * the area enclosing the border.
798    * Updates everything before returning the value.
799    * @param which Which size location to return. Possible values are MAX and MIN.
800    * @return The loation of the area.
801    */

802   final Point getSizeLocation (int which) {
803
804     updateArea();
805     return sizeLocations[which];
806   }
807
808
809   /**
810    * Returns the size of the space area. The size of the space area is the
811    * area size less the borders and gaps.
812    * Updates everything before returning the value.
813    * @param which Which space area size to return. Possible values are MAX and
814    * MIN.
815    * @return The size of the space area.
816    */

817   final Dimension getSpaceSize (int which) {
818
819     updateArea();
820     return spaceSizes[which];
821   }
822
823
824   /**
825    * Returns the specified ratio. Ratios area based on maximum area size
826    * divided by model area size. The width ratio uses the area widths. The
827    * height ratio uses the area heights. And the lesser ratio returns the
828    * lesser of these two.
829    * Updates everything before returning the value.
830    * @param which Which ratio to return. Possible values are WIDTH, HEIGHT, and
831    * LESSER.
832    * @return The ratio; value is between 0 and 1.
833    */

834   final float getRatio (int which) {
835     updateArea();
836     return ratios[which];
837   }
838
839
840   /**
841    * Returns the current justifications for the minimum area. Justifications
842    * are used only when justifications are enabled. Justifications auto
843    * locate the minimum area within the maximum area. This is only used when
844    * auto minimum area sizing is disabled.
845    * @param which Which justification to return. Possible values are HORIZONTAL
846    * and VERTICAL.
847    * @return The justification. Possible values for a horizontal
848    * justification are LEFT, RIGHT, and CENTER; values for a vertical
849    * justification are TOP, BOTTOM, and CENTER.
850    */

851   final int getJustifications (int which) {
852
853     return justifications[which];
854   }
855
856
857   /**
858    * Returns whether there exists a background or not.
859    * @return If there is, then true.
860    */

861   final boolean getBackgroundExistence() {
862
863     return backgroundExistence;
864   }
865
866
867   /**
868    * Returns the color of the background.
869    * @return The color of the background.
870    */

871   final Color getBackgroundColor() {
872
873     return backgroundColor;
874   }
875
876
877   /**
878    * Gets whether there exists borders. All must exist for this to return true.
879    * @return If true, then the borders do not exist.
880    */

881   final boolean getBorderExistence() {
882
883     return (borderExistences[LEFT] && borderExistences[RIGHT] &&
884     borderExistences[TOP] && borderExistences[BOTTOM]);
885   }
886
887
888   final boolean getBorderExistence (int which) {
889
890     return (borderExistences[which]);
891   }
892
893
894   /**
895    * Returns the color of the border (each border).
896    * @return The color of the border.
897    */

898   final Color getBorderColor() {
899
900     return borderColors[LEFT];
901   }
902
903
904   /**
905    * Returns the color of the border (specific border).
906    * @param which Which border you want the color of (BOTTOM, TOP, LEFT, RIGHT).
907    * @return The color of the chosen border.
908    */

909   final Color getBorderColor (int which) {
910
911     return borderColors[which];
912   }
913
914
915   /**
916    * Gets the thickness of the gap model. These values will be
917    * applied to a ratio to determine their final thicknesses. The ratio is the
918    * maximum size divided by the maximum model size. More information is in the
919    * introductory notes for this class.
920    * @return The model thickness for the gap.
921    */

922   final int getGapThicknessModel() {
923
924     return gapThicknessModels[LEFT];
925   }
926
927
928   /**
929    * Gets whether there exists gaps. All must exist for this to return true.
930    * @return If true, then the gaps do not exist.
931    */

932   final boolean getGapExistence() {
933
934     return (gapExistences[LEFT] && gapExistences[RIGHT] &&
935     gapExistences[TOP] && gapExistences[BOTTOM]);
936   }
937
938
939   final boolean getGapExistence (int which) {
940     return (gapExistences[which]);
941   }
942
943
944   /**
945    * Returns the thickness of one of the gaps. Should be used only when all
946    * gaps have same thickness model.
947    * @return The thickness of the gap.
948    */

949   final int getGapThickness() {
950     updateArea();
951     return gapThicknesses[LEFT];
952   }
953
954
955   /**
956    * Returns the thickness of one of the gaps. Should be used only when all
957    * gaps have same thickness model.
958    * @param which Which gap to return the thickness of.
959    * @return The thickness of the gap.
960    */

961   final int getGapThickness (int which) {
962     updateArea();
963     return gapThicknesses[which];
964   }
965
966
967   /**
968    * Gets the thickness of the border model. These values will be
969    * applied to a ratio to determine their final thicknesses. The ratio is the
970    * maximum size divided by the maximum model size. More information is in the
971    * introductory notes for this class.
972    * @return The model thickness for the border.
973    */

974   final int getBorderThicknessModel() {
975
976     return borderThicknessModels[LEFT];
977   }
978
979
980   /**
981    * Gets the thickness of a border model. These values will be
982    * applied to a ratio to determine their final thicknesses. The ratio is the
983    * maximum size divided by the maximum model size. More information is in the
984    * introductory notes for this class.
985    * @return The model thickness for this border.
986    */

987   final int getBorderThicknessModel(int which) {
988     return borderThicknessModels[which];
989   }
990
991
992   /**
993    * Returns the thickness of a border.
994    * @return The thickness of the particular border.
995    */

996   final int getBorderThickness (int which) {
997     updateArea();
998     return borderThicknesses[which];
999   }
1000
1001
1002  /**
1003   * Returns the thickness of a border + the gap.
1004   * @return The thickness of the border + the gap.
1005   */

1006  final int getOffsetThickness() {
1007    updateArea();
1008    return borderThicknesses[LEFT] + gapThicknesses[LEFT];
1009  }
1010
1011
1012  /**
1013   * Returns the thickness of the border.
1014   * @return The thickness of the border.
1015   */

1016  final int getBorderThickness() {
1017    updateArea();
1018    return borderThicknesses[TOP];
1019  }
1020
1021
1022  /**
1023   * Indicates whether some property of this class has changed.
1024   * @return True if some property has changed.
1025   */

1026  final boolean getAreaNeedsUpdate () {
1027
1028    return needsUpdate;
1029  }
1030
1031
1032  /**
1033   * Applies the given ratio to the given integer.
1034   * @param model The integer.
1035   * @param ratio The ratio.
1036   * @return The ratio multiplied by the integer.
1037   */

1038  final int applyRatio (int model, float ratio) {
1039
1040    int applied = (int)(ratio * model);
1041    applied = applied < 1 && model > 0 ? 1 : applied;
1042    return applied;
1043  }
1044
1045
1046  /**
1047   * Returns whether the max model will be reset, in the next max sizing.
1048   * @return True if the max model size needs to be reset.
1049   */

1050  final boolean getResetAreaModel () {
1051
1052    return resetAreaModel;
1053  }
1054
1055
1056  /**
1057   * Updates this area. This area maintains many variables. Calling this
1058   * methods assures they are all updates with respect to eachother.
1059   */

1060  final void updateArea () {
1061
1062    if (getAreaNeedsUpdate()) {
1063      update();
1064    }
1065    needsUpdate = false;
1066  }
1067
1068
1069  /**
1070   * Resets the model for this class. The model is used for shrinking and
1071   * growing of its components based on the maximum size of this class. If this
1072   * method is called, then the next time the maximum size is set, this classes
1073   * model maximum size will be made equal to the new maximum size. Effectively
1074   * what this does is ensure that whenever this objects maximum size is equal
1075   * to the one given, then all of the components will take on their default
1076   * model sizes. Note: This is only useful when auto model max sizing is
1077   * disabled.
1078   * @param reset True causes the max model size to be set upon the next max
1079   * sizing.
1080   */

1081  final void resetAreaModel (boolean reset) {
1082
1083    if (reset != resetAreaModel) {
1084      needsUpdate = true;
1085      resetAreaModel = reset;
1086      unsetAreaModelOnUpdate = false;
1087    }
1088  }
1089
1090
1091  /**
1092   * Paints this bordered area. Paints borders and background if they exist.
1093   * Updates everything before painting.
1094   * @param g2D The graphics context for calculations and painting.
1095   */

1096  void paintComponent (Graphics2D g2D) {
1097
1098    updateArea();
1099    Paint oldPaint = g2D.getPaint();
1100    g2D.setPaint (backgroundPaint);
1101    g2D.fill (background);
1102    g2D.setPaint (borderColors[LEFT]);
1103    g2D.fill (borders[LEFT]);
1104    g2D.setPaint (borderColors[RIGHT]);
1105    g2D.fill (borders[RIGHT]);
1106    g2D.setPaint (borderColors[TOP]);
1107    g2D.fill (borders[TOP]);
1108    g2D.setPaint (borderColors[BOTTOM]);
1109    g2D.fill (borders[BOTTOM]);
1110    g2D.setPaint (oldPaint);
1111  }
1112
1113
1114  private void createObjects() {
1115
1116    sizeLocations = new Point[3];
1117    sizeLocations[MAX] = new Point();
1118    sizeLocations[MIN] = new Point();
1119
1120    spaceSizeLocations = new Point[3];
1121    spaceSizeLocations[MAX] = new Point();
1122    spaceSizeLocations[MIN] = new Point();
1123
1124    autoSizes = new boolean[3];
1125    sizes = new Dimension[3];
1126    sizes[MAX] = new Dimension();
1127    sizes[MAXMODEL] = new Dimension();
1128    sizes[MIN] = new Dimension();
1129
1130    spaceSizes = new Dimension[3];
1131    spaceSizes[MAX] = new Dimension();
1132    spaceSizes[MIN] = new Dimension();
1133
1134    autoJustifys = new boolean[2];
1135    justifications = new int[2];
1136
1137    ratios = new float[3];
1138    customizeRatios = new boolean[3];
1139
1140    background = new Rectangle();
1141
1142    borderExistences = new boolean[4];
1143    borders = new Rectangle[4];
1144    borders[LEFT] = new Rectangle();
1145    borders[RIGHT] = new Rectangle();
1146    borders[TOP] = new Rectangle();
1147    borders[BOTTOM] = new Rectangle();
1148    borderThicknesses = new int[4];
1149    borderThicknessModels = new int[4];
1150    borderCornerAssociations = new int[6];
1151    borderAssociations = new boolean[6];
1152    borderColors = new Color[6];
1153
1154    gapExistences = new boolean[4];
1155    gapThicknesses = new int[4];
1156    gapThicknessModels = new int[4];
1157    gapAssociations = new boolean[6];
1158  }
1159
1160
1161  private void update() {
1162
1163    if (unsetAreaModelOnUpdate) resetAreaModel = false;
1164    updateMaxSizeObjects();
1165    updateRatios();
1166    updateBorderThicknesses();
1167    updateGapThicknesses();
1168    updateMaxSpaceSizeObjects();
1169    updateMinObjects();
1170    updateBackground();
1171    updateBorderRectangles();
1172    updateBackgroundPaint();
1173  }
1174
1175
1176  private void updateMaxSizeObjects() {
1177
1178    sizes[MAXMODEL] = autoSizes[MAXMODEL] ? sizes[MAX] : sizes[MAXMODEL];
1179  }
1180
1181
1182  private void updateRatios() {
1183
1184    if (!customizeRatios[WIDTH]) {
1185      ratios[WIDTH] = sizes[MAXMODEL].width == 0 ? 0f :
1186        (float)sizes[MAX].width / sizes[MAXMODEL].width;
1187    }
1188    if (!customizeRatios[HEIGHT]) {
1189      ratios[HEIGHT] = sizes[MAXMODEL].height == 0 ? 0f :
1190        (float)sizes[MAX].height / sizes[MAXMODEL].height;
1191    }
1192    if (!customizeRatios[LESSER]) {
1193      ratios[LESSER] =
1194        ratios[WIDTH] < ratios[HEIGHT] ? ratios[WIDTH] : ratios[HEIGHT];
1195    }
1196    if (lockRatios) {
1197      ratios[WIDTH] = ratios[LESSER];
1198      ratios[HEIGHT] = ratios[LESSER];
1199    }
1200  }
1201
1202
1203  private void updateBorderThicknesses() {
1204
1205    if (borderExistences[LEFT]) {
1206      if ((borderAssociations[LEFTTOP] && borderExistences[TOP]) ||
1207        (borderAssociations[LEFTBOTTOM] && borderExistences[BOTTOM])) {
1208        borderThicknesses[LEFT] =
1209          applyRatio (borderThicknessModels[LEFT], ratios[LESSER]);
1210      }
1211      else {
1212        borderThicknesses[LEFT] =
1213          applyRatio (borderThicknessModels[LEFT], ratios[WIDTH]);
1214      }
1215    }
1216    else borderThicknesses[LEFT] = 0;
1217
1218    if (borderExistences[RIGHT]) {
1219      if ((borderAssociations[RIGHTTOP] && borderExistences[TOP]) ||
1220        (borderAssociations[RIGHTBOTTOM] && borderExistences[BOTTOM])) {
1221        borderThicknesses[RIGHT] =
1222          applyRatio (borderThicknessModels[RIGHT], ratios[LESSER]);
1223      }
1224      else {
1225        borderThicknesses[RIGHT] =
1226          applyRatio (borderThicknessModels[RIGHT], ratios[WIDTH]);
1227      }
1228    }
1229    else borderThicknesses[RIGHT] = 0;
1230
1231    if (borderExistences[TOP]) {
1232      if ((borderAssociations[LEFTTOP] && borderExistences[LEFT]) ||
1233        (borderAssociations[RIGHTTOP] && borderExistences[RIGHT])) {
1234        borderThicknesses[TOP] =
1235          applyRatio (borderThicknessModels[TOP], ratios[LESSER]);
1236      }
1237      else {
1238        borderThicknesses[TOP] =
1239          applyRatio (borderThicknessModels[TOP], ratios[HEIGHT]);
1240      }
1241    }
1242    else borderThicknesses[TOP] = 0;
1243
1244    if (borderExistences[BOTTOM]) {
1245      if ((borderAssociations[LEFTBOTTOM] && borderExistences[LEFT]) ||
1246        (borderAssociations[RIGHTBOTTOM] && borderExistences[RIGHT])) {
1247        borderThicknesses[BOTTOM] =
1248          applyRatio (borderThicknessModels[BOTTOM], ratios[LESSER]);
1249      }
1250      else {
1251        borderThicknesses[BOTTOM] =
1252          applyRatio (borderThicknessModels[BOTTOM], ratios[HEIGHT]);
1253      }
1254    }
1255    else borderThicknesses[BOTTOM] = 0;
1256
1257    int availableWidth = sizes[MAX].width;
1258    if (borderExistences[LEFT]) {
1259      if (borderAssociations[LEFTTOP] && borderExistences[TOP]) {
1260        borderThicknesses[LEFT] =
1261          borderThicknesses[LEFT] > borderThicknesses[TOP] ?
1262          borderThicknesses[TOP] : borderThicknesses[LEFT];
1263      }
1264      if (borderAssociations[LEFTBOTTOM] && borderExistences[BOTTOM]) {
1265        borderThicknesses[LEFT] =
1266          borderThicknesses[LEFT] > borderThicknesses[BOTTOM] ?
1267          borderThicknesses[BOTTOM] : borderThicknesses[LEFT];
1268      }
1269      borderThicknesses[LEFT] = borderThicknesses[LEFT] > availableWidth ?
1270        availableWidth : borderThicknesses[LEFT];
1271      availableWidth -= borderThicknesses[LEFT];
1272    }
1273
1274    if (borderExistences[RIGHT]) {
1275      if (borderAssociations[RIGHTTOP] && borderExistences[TOP]) {
1276        borderThicknesses[RIGHT] =
1277          borderThicknesses[RIGHT] > borderThicknesses[TOP] ?
1278          borderThicknesses[TOP] : borderThicknesses[RIGHT];
1279      }
1280      if (borderAssociations[RIGHTBOTTOM] && borderExistences[BOTTOM]) {
1281        borderThicknesses[RIGHT] =
1282          borderThicknesses[RIGHT] > borderThicknesses[BOTTOM] ?
1283          borderThicknesses[BOTTOM] : borderThicknesses[RIGHT];
1284      }
1285      borderThicknesses[RIGHT] = borderThicknesses[RIGHT] > availableWidth ?
1286        availableWidth : borderThicknesses[RIGHT];
1287    }
1288
1289    int availableHeight = sizes[MAX].height;
1290    if (borderExistences[TOP]) {
1291      if (borderAssociations[LEFTTOP] && borderExistences[LEFT]) {
1292        borderThicknesses[TOP] =
1293          borderThicknesses[TOP] > borderThicknesses[LEFT] ?
1294          borderThicknesses[TOP] : borderThicknesses[TOP];
1295      }
1296      if (borderAssociations[RIGHTTOP] && borderExistences[RIGHT]) {
1297        borderThicknesses[TOP] =
1298          borderThicknesses[TOP] > borderThicknesses[RIGHT] ?
1299          borderThicknesses[BOTTOM] : borderThicknesses[TOP];
1300      }
1301      borderThicknesses[TOP] = borderThicknesses[TOP] > availableHeight ?
1302        availableHeight : borderThicknesses[TOP];
1303      availableHeight -= borderThicknesses[TOP];
1304    }
1305
1306    if (borderExistences[BOTTOM]) {
1307      if (borderAssociations[LEFTBOTTOM] && borderExistences[LEFT]) {
1308        borderThicknesses[BOTTOM] =
1309          borderThicknesses[BOTTOM] > borderThicknesses[LEFT] ?
1310          borderThicknesses[BOTTOM] : borderThicknesses[BOTTOM];
1311      }
1312      if (borderAssociations[RIGHTBOTTOM] && borderExistences[RIGHT]) {
1313        borderThicknesses[BOTTOM] =
1314          borderThicknesses[BOTTOM] > borderThicknesses[RIGHT] ?
1315          borderThicknesses[BOTTOM] : borderThicknesses[BOTTOM];
1316      }
1317      borderThicknesses[BOTTOM] = borderThicknesses[BOTTOM] > availableHeight ?
1318        availableHeight : borderThicknesses[BOTTOM];
1319    }
1320  }
1321
1322
1323  private void updateGapThicknesses () {
1324
1325    if (gapExistences[LEFT]) {
1326      if ((gapAssociations[LEFTTOP] && gapExistences[TOP]) ||
1327        (gapAssociations[LEFTBOTTOM] && gapExistences[BOTTOM])) {
1328        gapThicknesses[LEFT] =
1329          applyRatio (gapThicknessModels[LEFT], ratios[LESSER]);
1330      }
1331      else {
1332        gapThicknesses[LEFT] =
1333          applyRatio (gapThicknessModels[LEFT], ratios[WIDTH]);
1334      }
1335    }
1336    else gapThicknesses[LEFT] = 0;
1337
1338    if (gapExistences[RIGHT]) {
1339      if ((gapAssociations[RIGHTTOP] && gapExistences[TOP]) ||
1340        (gapAssociations[RIGHTBOTTOM] && gapExistences[BOTTOM])) {
1341        gapThicknesses[RIGHT] =
1342          applyRatio (gapThicknessModels[RIGHT], ratios[LESSER]);
1343      }
1344      else {
1345        gapThicknesses[RIGHT] =
1346          applyRatio (gapThicknessModels[RIGHT], ratios[WIDTH]);
1347      }
1348    }
1349    else gapThicknesses[RIGHT] = 0;
1350
1351    if (gapExistences[TOP]) {
1352      if ((gapAssociations[LEFTTOP] && gapExistences[LEFT]) ||
1353        (gapAssociations[RIGHTTOP] && gapExistences[RIGHT])) {
1354        gapThicknesses[TOP] =
1355          applyRatio (gapThicknessModels[TOP], ratios[LESSER]);
1356      }
1357      else {
1358        gapThicknesses[TOP] =
1359          applyRatio (gapThicknessModels[TOP], ratios[HEIGHT]);
1360      }
1361    }
1362    else gapThicknesses[TOP] = 0;
1363
1364    if (gapExistences[BOTTOM]) {
1365      if ((gapAssociations[LEFTBOTTOM] && gapExistences[LEFT]) ||
1366        (gapAssociations[RIGHTBOTTOM] && gapExistences[RIGHT])) {
1367        gapThicknesses[BOTTOM] =
1368          applyRatio (gapThicknessModels[BOTTOM], ratios[LESSER]);
1369      }
1370      else {
1371        gapThicknesses[BOTTOM] =
1372          applyRatio (gapThicknessModels[BOTTOM], ratios[HEIGHT]);
1373      }
1374    }
1375    else gapThicknesses[BOTTOM] = 0;
1376
1377    int availableWidth =
1378      sizes[MAX].width - borderThicknesses[LEFT] - borderThicknesses[RIGHT];
1379    if (gapExistences[LEFT]) {
1380      if (gapAssociations[LEFTTOP] && gapExistences[TOP]) {
1381        gapThicknesses[LEFT] = gapThicknesses[LEFT] > gapThicknesses[TOP] ?
1382          gapThicknesses[TOP] : gapThicknesses[LEFT];
1383      }
1384      if (gapAssociations[LEFTBOTTOM] && gapExistences[BOTTOM]) {
1385        gapThicknesses[LEFT] = gapThicknesses[LEFT] > gapThicknesses[BOTTOM] ?
1386          gapThicknesses[BOTTOM] : gapThicknesses[LEFT];
1387      }
1388      gapThicknesses[LEFT] = gapThicknesses[LEFT] > availableWidth ?
1389        availableWidth : gapThicknesses[LEFT];
1390      availableWidth -= gapThicknesses[LEFT];
1391    }
1392
1393    if (gapExistences[RIGHT]) {
1394      if (gapAssociations[RIGHTTOP] && gapExistences[TOP]) {
1395        gapThicknesses[RIGHT] = gapThicknesses[RIGHT] > gapThicknesses[TOP] ?
1396          gapThicknesses[TOP] : gapThicknesses[RIGHT];
1397      }
1398      if (gapAssociations[RIGHTBOTTOM] && gapExistences[BOTTOM]) {
1399        gapThicknesses[RIGHT] = gapThicknesses[RIGHT] > gapThicknesses[BOTTOM] ?
1400          gapThicknesses[BOTTOM] : gapThicknesses[RIGHT];
1401      }
1402      gapThicknesses[RIGHT] = gapThicknesses[RIGHT] > availableWidth ?
1403        availableWidth : gapThicknesses[RIGHT];
1404    }
1405
1406    int availableHeight =
1407      sizes[MAX].height - borderThicknesses[TOP] - borderThicknesses[BOTTOM];
1408    if (gapExistences[TOP]) {
1409      if (gapAssociations[LEFTTOP] && gapExistences[LEFT]) {
1410        gapThicknesses[TOP] = gapThicknesses[TOP] > gapThicknesses[LEFT] ?
1411          gapThicknesses[TOP] : gapThicknesses[TOP];
1412      }
1413      if (gapAssociations[RIGHTTOP] && gapExistences[RIGHT]) {
1414        gapThicknesses[TOP] = gapThicknesses[TOP] > gapThicknesses[RIGHT] ?
1415          gapThicknesses[BOTTOM] : gapThicknesses[TOP];
1416      }
1417      gapThicknesses[TOP] = gapThicknesses[TOP] > availableHeight ?
1418        availableHeight : gapThicknesses[TOP];
1419      availableHeight -= gapThicknesses[TOP];
1420    }
1421
1422    if (gapExistences[BOTTOM]) {
1423      if (gapAssociations[LEFTBOTTOM] && gapExistences[LEFT]) {
1424        gapThicknesses[BOTTOM] = gapThicknesses[BOTTOM] > gapThicknesses[LEFT] ?
1425          gapThicknesses[BOTTOM] : gapThicknesses[BOTTOM];
1426      }
1427      if (gapAssociations[RIGHTBOTTOM] && gapExistences[RIGHT]) {
1428        gapThicknesses[BOTTOM] =
1429          gapThicknesses[BOTTOM] > gapThicknesses[RIGHT] ?
1430          gapThicknesses[BOTTOM] : gapThicknesses[BOTTOM];
1431      }
1432      gapThicknesses[BOTTOM] = gapThicknesses[BOTTOM] > availableHeight ?
1433        availableHeight : gapThicknesses[BOTTOM];
1434    }
1435  }
1436
1437
1438  private void updateMaxSpaceSizeObjects() {
1439
1440    spaceSizeLocations[MAX] = new Point (
1441      sizeLocations[MAX].x + borderThicknesses[LEFT] + gapThicknesses[LEFT],
1442      sizeLocations[MAX].y + borderThicknesses[TOP] + gapThicknesses[TOP]);
1443    spaceSizes[MAX] = new Dimension (
1444      sizes[MAX].width - (borderThicknesses[LEFT] + borderThicknesses[RIGHT]) -
1445        (gapThicknesses[LEFT] + gapThicknesses[RIGHT]),
1446      sizes[MAX].height - (borderThicknesses[TOP] + borderThicknesses[BOTTOM]) -
1447        (gapThicknesses[TOP] + gapThicknesses[BOTTOM]));
1448  }
1449
1450
1451  private void updateMinObjects() {
1452
1453    if (autoSizes[MIN]) {
1454      sizeLocations[MIN] = sizeLocations[MAX];
1455      sizes[MIN] = sizes[MAX];
1456      spaceSizeLocations[MIN] = spaceSizeLocations[MAX];
1457      spaceSizes[MIN] = spaceSizes[MAX];
1458    }
1459
1460    else {
1461
1462      //spaceSizes[MIN] is set by sub-class
1463
sizes[MIN] = new Dimension (
1464        spaceSizes[MIN].width + borderThicknesses[LEFT] +
1465        borderThicknesses[RIGHT] + gapThicknesses[LEFT] + gapThicknesses[RIGHT],
1466        spaceSizes[MIN].height + borderThicknesses[TOP] +
1467        borderThicknesses[BOTTOM] + gapThicknesses[TOP] +
1468        gapThicknesses[BOTTOM]);
1469
1470      //find locations
1471
int x = -1, y = -1;
1472      if (autoJustifys[HORIZONTAL]) {
1473        if (justifications[HORIZONTAL] == LEFT) {
1474          x = sizeLocations[MAX].x;
1475        }
1476        else if (justifications[HORIZONTAL] == RIGHT) {
1477          x = sizeLocations[MAX].x + sizes[MAX].width - sizes[MIN].width;
1478        }
1479        else if (justifications[HORIZONTAL] == CENTER) {
1480          x = sizeLocations[MAX].x +
1481            (int)((sizes[MAX].width - sizes[MIN].width) / 2);
1482        }
1483      }
1484      else x = spaceSizeLocations[MIN].x -
1485        borderThicknesses[LEFT] - gapThicknesses[LEFT];
1486      if (autoJustifys[VERTICAL]) {
1487        if (justifications[VERTICAL] == TOP) {
1488          y = sizeLocations[MAX].y;
1489        }
1490        else if (justifications[VERTICAL] == BOTTOM) {
1491          y = sizeLocations[MAX].y + sizes[MAX].height - sizes[MIN].height;
1492        }
1493        else if (justifications[VERTICAL] == CENTER) {
1494          y = sizeLocations[MAX].y +
1495            (int)((sizes[MAX].height - sizes[MIN].height) / 2);
1496        }
1497      }
1498      else y = spaceSizeLocations[MIN].y -
1499        borderThicknesses[TOP] - gapThicknesses[TOP];
1500      sizeLocations[MIN] = new Point (x, y);
1501
1502      spaceSizeLocations[MIN] = new Point (
1503        x + borderThicknesses[LEFT] + gapThicknesses[LEFT],
1504          y + borderThicknesses[TOP] + gapThicknesses[TOP]);
1505    }
1506  }
1507
1508
1509  private void updateBackground() {
1510
1511    if (backgroundExistence) {
1512    background = new Rectangle (sizeLocations[MIN].x, sizeLocations[MIN].y,
1513      sizes[MIN].width, sizes[MIN].height);
1514    }
1515    else background = new Rectangle();
1516  }
1517
1518
1519  private void updateBorderRectangles() {
1520
1521    boolean[] usedCorner = new boolean[4];
1522
1523    if (borderCornerAssociations[LEFTTOP] == LEFT) {
1524
1525      borders[LEFT].setLocation (sizeLocations[MIN]);
1526      borders[TOP].setLocation (sizeLocations[MIN].x + borderThicknesses[LEFT],
1527        sizeLocations[MIN].y);
1528    }
1529    else {
1530      borders[LEFT].setLocation (sizeLocations[MIN].x,
1531        sizeLocations[MIN].y + borderThicknesses[TOP]);
1532      borders[TOP].setLocation (sizeLocations[MIN]);
1533    }
1534
1535    if (borderCornerAssociations[RIGHTTOP] == RIGHT) {
1536
1537      borders[RIGHT].setLocation (
1538        sizeLocations[MIN].x + sizes[MIN].width - borderThicknesses[RIGHT],
1539        sizeLocations[MIN].y);
1540    }
1541    else {
1542
1543      borders[RIGHT].setLocation (
1544        sizeLocations[MIN].x + sizes[MIN].width - borderThicknesses[RIGHT],
1545        sizeLocations[MIN].y + borderThicknesses[TOP]);
1546    }
1547
1548    if (borderCornerAssociations[LEFTBOTTOM] == BOTTOM) {
1549      borders[BOTTOM].setLocation (sizeLocations[MIN].x,
1550        sizeLocations[MIN].y + sizes[MIN].height - borderThicknesses[BOTTOM]);
1551    }
1552    else {
1553      borders[BOTTOM].setLocation (
1554        sizeLocations[MIN].x + borderThicknesses[LEFT],
1555        sizeLocations[MIN].y + sizes[MIN].height - borderThicknesses[BOTTOM]);
1556    }
1557
1558    int delta = 0;
1559    delta += (borderCornerAssociations[LEFTTOP] == LEFT ?
1560      0 : borderThicknesses[TOP]);
1561    delta += (borderCornerAssociations[LEFTBOTTOM] == LEFT ?
1562      0 : borderThicknesses[BOTTOM]);
1563    borders[LEFT].setSize (borderThicknesses[LEFT], sizes[MIN].height - delta);
1564
1565    delta = 0;
1566    delta += (borderCornerAssociations[RIGHTTOP] == RIGHT ?
1567      0 : borderThicknesses[TOP]);
1568    delta += (borderCornerAssociations[RIGHTBOTTOM] == RIGHT ?
1569      0 : borderThicknesses[BOTTOM]);
1570    borders[RIGHT].setSize (
1571      borderThicknesses[RIGHT], sizes[MIN].height - delta);
1572
1573    delta = 0;
1574    delta += (borderCornerAssociations[LEFTTOP] == TOP ?
1575      0 : borderThicknesses[LEFT]);
1576    delta += (borderCornerAssociations[RIGHTTOP] == TOP ?
1577      0 : borderThicknesses[RIGHT]);
1578    borders[TOP].setSize (sizes[MIN].width - delta, borderThicknesses[TOP]);
1579
1580    delta = 0;
1581    delta += (borderCornerAssociations[LEFTBOTTOM] == BOTTOM ?
1582      0 : borderThicknesses[LEFT]);
1583    delta += (borderCornerAssociations[RIGHTBOTTOM] == BOTTOM ?
1584      0 : borderThicknesses[RIGHT]);
1585    borders[BOTTOM].setSize (
1586      sizes[MIN].width - delta, borderThicknesses[BOTTOM]);
1587  }
1588
1589
1590  private void updateBackgroundPaint() {
1591
1592    if (lightSource == TOP) {
1593      backgroundPaint = new GradientPaint (
1594        sizeLocations[MIN].x, sizeLocations[MIN].y, backgroundColor.brighter(),
1595        sizeLocations[MIN].x, sizeLocations[MIN].y + sizes[MIN].height, backgroundColor);
1596    }
1597    else if (lightSource == BOTTOM) {
1598      backgroundPaint = new GradientPaint (
1599        sizeLocations[MIN].x, sizeLocations[MIN].y, backgroundColor,
1600        sizeLocations[MIN].x, sizeLocations[MIN].y + sizes[MIN].height, backgroundColor.brighter());
1601    }
1602    else if (lightSource == LEFT) {
1603      backgroundPaint = new GradientPaint (
1604        sizeLocations[MIN].x, sizeLocations[MIN].y, backgroundColor.brighter(),
1605        sizeLocations[MIN].x + sizes[MIN].width, sizeLocations[MIN].y, backgroundColor);
1606    }
1607    else if (lightSource == RIGHT) {
1608      backgroundPaint = new GradientPaint (
1609        sizeLocations[MIN].x, sizeLocations[MIN].y, backgroundColor,
1610        sizeLocations[MIN].x + sizes[MIN].width, sizeLocations[MIN].y, backgroundColor.brighter());
1611    }
1612    else {
1613      backgroundPaint = backgroundColor;
1614    }
1615  }
1616}
Popular Tags