xref: /titanic_41/usr/src/cmd/krb5/kadmin/gui/visualrt/sunsoft/jws/visual/rt/awt/GBLayout.java (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * ident	"%Z%%M%	%I%	%E% SMI"
24  *
25  * @(#)GBLayout.java	1.23 97/09/03 Doug Stein
26  *
27  * Copyright (c) 1996, 2001 by Sun Microsystems, Inc.
28  * All rights reserved.
29  *
30  * Permission to use, copy, modify, and distribute this software
31  * and its documentation for NON-COMMERCIAL purposes and without
32  * fee is hereby granted provided that this copyright notice
33  * appears in all copies. Please refer to the file "copyright.html"
34  * for further important copyright and licensing information.
35  *
36  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
37  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
38  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
40  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
41  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
42  */
43 package sunsoft.jws.visual.rt.awt;
44 
45 import sunsoft.jws.visual.rt.base.Global;
46 
47 import java.awt.*;
48 import java.util.Hashtable;
49 
50 class GBLayoutInfo {
51     int width, height;	/* number of cells horizontally, vertically */
52     int startx, starty;		/* starting point for layout */
53     int minWidth[];		/* largest minWidth in each column */
54     int minHeight[];		/* largest minHeight in each row */
55     double weightX[];		/* largest weight in each column */
56     double weightY[];		/* largest weight in each row */
57 
GBLayoutInfo(int w, int h)58     GBLayoutInfo(int w, int h) {
59         width = w;
60         height = h;
61         minWidth = new int[w];
62         minHeight = new int[h];
63         weightX = new double[w];
64         weightY = new double[h];
65     }
66 }
67 
68 /* BEGIN JSTYLED */
69 /**
70    GBLayout is a flexible layout manager
71    that aligns components vertically and horizontally,
72    without requiring that the components be the same size.
73    Each GBLayout uses a rectangular grid of cells,
74    with each component occupying one or more cells
75    (called its  < em >display area</em>).
76    Each component managed by a GBLayout
77    is associated with a
78    < a href = java.awt.GBConstraints.html >GBConstraints</a>  instance
79    that specifies how the component is laid out
80    within its display area.
81    How a GBLayout places a set of components
82    depends on each component's GBConstraints and minimum size,
83    as well as the preferred size of the components' container.
84    < p>
85 
86    To use a GBLayout effectively,
87    you must customize one or more of its components' GBConstraints.
88    You customize a GBConstraints object by setting one or more
89    of its instance variables:
90    < dl>
91    < dt > <a href = java.awt.GBConstraints.html#gridx> gridx</a>,
92    < a href = java.awt.GBConstraints.html#gridy> gridy</a>
93    < dd>  Specifies the cell at the upper left of the component's display area,
94    where the upper-left-most cell has address gridx  =  0, gridy=0.
95    Use GBConstraints.RELATIVE(the default value)
96    to specify that the component be just placed
97    just to the right of(for gridx)
98    or just below(for gridy)
99    the component that was added to the container
100    just before this component was added.
101    < dt > <a href = java.awt.GBConstraints.html#gridwidth> gridwidth</a>,
102    < a href = java.awt.GBConstraints.html#gridheight> gridheight</a>
103    < dd>  Specifies the number of cells in a row(for gridwidth)
104    or column(for gridheight)
105    in the component's display area.
106    The default value is 1.
107    Use GBConstraints.REMAINDER to specify
108    that the component be the last one in its row(for gridwidth)
109    or column(for gridheight).
110    Use GBConstraints.RELATIVE to specify
111    that the component be the next to last one
112    in its row(for gridwidth) or column (for gridheight).
113    < dt>  <a href = java.awt.GBConstraints.html#fill>fill</a>
114    < dd>  Used when the component's display area
115    is larger than the component's requested size
116    to determine whether(and how) to resize the component.
117    Valid values are
118    GBConstraints.NONE
119    (the default),
120    GBConstraints.HORIZONTAL
121    (make the component wide enough to fill its display area
122    horizontally, but don't change its height),
123    GBConstraints.VERTICAL
124    (make the component tall enough to fill its display area
125    vertically, but don't change its width),
126    and
127    GBConstraints.BOTH
128    (make the component fill its display area entirely).
129    < dt > <a href = java.awt.GBConstraints.html#ipadx> ipadx</a>,
130    < a href = java.awt.GBConstraints.html#ipady> ipady</a>
131    < dd>  Specifies the internal padding:
132    how much to add to the minimum size of the component.
133    The width of the component will be at least
134    its minimum width plus ipadx*2 pixels
135    (since the padding applies to both sides of the component).
136    Similarly, the height of the component will be at least
137    the minimum height plus ipady*2 pixels.
138    < dt>  <a href = java.awt.GBConstraints.html#insets>insets</a>
139    < dd>  Specifies the external padding of the component --
140    the minimum amount of space between the component
141    and the edges of its display area.
142    < dt>  <a href = java.awt.GBConstraints.html#anchor>anchor</a>
143    < dd>  Used when the component is smaller than its display area
144    to determine where(within the area) to place the component.
145    Valid values are
146    GBConstraints.CENTER(the default),
147    GBConstraints.NORTH,
148    GBConstraints.NORTHEAST,
149    GBConstraints.EAST,
150    GBConstraints.SOUTHEAST,
151    GBConstraints.SOUTH,
152    GBConstraints.SOUTHWEST,
153    GBConstraints.WEST, and
154    GBConstraints.NORTHWEST.
155    < dt > <a href = java.awt.GBConstraints.html#weightx> weightx</a>,
156    < a href = java.awt.GBConstraints.html#weighty> weighty</a>
157    < dd>  Used to determine how to distribute space;
158    this is important for specifying resizing behavior.
159    Unless you specify a weight
160    for at least one component in a row(weightx)
161    and column(weighty),
162    all the components clump together in the center of
163    their container.
164    This is because when the weight is zero(the default),
165    the GBLayout puts any extra space
166    between its grid of cells and the edges of the container.
167    < /dl>
168 
169    The following figure shows ten components(all buttons)
170    managed by a GBLayout:
171    < blockquote>
172    < img src  =  images/java.awt/GridBagEx.gif width=262 height=155>
173    < /blockquote>
174 
175    All the components have fill = GBConstraints.BOTH.
176    In addition, the components have the following non-default constraints:
177    < ul>
178    < li >Button1, Button2, Button3:
179    weightx = 1.0
180    < li >Button4:
181    weightx = 1.0,
182    gridwidth = GBConstraints.REMAINDER
183    < li >Button5:
184    gridwidth = GBConstraints.REMAINDER
185    < li >Button6:
186    gridwidth = GBConstraints.RELATIVE
187    < li >Button7:
188    gridwidth = GBConstraints.REMAINDER
189    < li >Button8:
190    gridheight  =  2, weighty=1.0,
191    < li >Button9, Button 10:
192    gridwidth = GBConstraints.REMAINDER
193    < /ul>
194 
195    Here is the code that implements the example shown above:
196    < blockquote>
197    < pre>
198    import java.awt.*;
199    import java.util.*;
200    import java.applet.Applet;
201 
202    public class GridBagEx1 extends Applet {
203 
204    protected void makebutton(String name,
205    GBLayout gridbag,
206    GBConstraints c) {
207    Button button = new Button(name);
208    gridbag.setConstraints(button, c);
209    add(button);
210    }
211 
212    public void init() {
213    GBLayout gridbag = new GBLayout();
214    GBConstraints c = new GBConstraints();
215 
216    setFont(new Font("Sansserif", Font.PLAIN, 14));
217    setLayout(gridbag);
218 
219    c.fill = GBConstraints.BOTH;
220    c.weightx = 1.0;
221    makebutton("Button1", gridbag, c);
222    makebutton("Button2", gridbag, c);
223    makebutton("Button3", gridbag, c);
224 
225    c.gridwidth = GBConstraints.REMAINDER; // end row
226    makebutton("Button4", gridbag, c);
227 
228    c.weightx = 0.0;		   // reset to the default
229    makebutton("Button5", gridbag, c); // another row
230 
231    c.gridwidth = GBConstraints.RELATIVE; // next-to-last in row
232    makebutton("Button6", gridbag, c);
233 
234    c.gridwidth = GBConstraints.REMAINDER; // end row
235    makebutton("Button7", gridbag, c);
236 
237    c.gridwidth = 1;	   	   // reset to the default
238    c.gridheight = 2;
239    c.weighty = 1.0;
240    makebutton("Button8", gridbag, c);
241 
242    c.weighty = 0.0;		   // reset to the default
243    c.gridwidth = GBConstraints.REMAINDER; // end row
244    c.gridheight = 1;		   // reset to the default
245    makebutton("Button9", gridbag, c);
246    makebutton("Button10", gridbag, c);
247 
248    resize(300, 100);
249    }
250 
251    public static void main(String args[]) {
252    Frame f = new Frame("GridBag Layout Example");
253    GridBagEx1 ex1 = new GridBagEx1();
254 
255    ex1.init();
256 
257    f.add("Center", ex1);
258    f.pack();
259    f.resize(f.getPreferredSize());
260    f.show();
261    }
262    }
263    < /pre>
264    < /blockquote>
265    *
266    * @version 1.23, 08/06/97
267    * @author Doug Stein
268    */
269 /* END JSTYLED */
270 public class GBLayout implements LayoutManager {
271 
272     /**
273      * Determines the minimum widths for the grid columns.
274      */
275     public int columnWidths[];
276 
277     /**
278      * Determines the minimum heights for the grid rows.
279      */
280     public int rowHeights[];
281 
282     /**
283      * Determines the minimum weights for the grid columns.
284      */
285     public double columnWeights[];
286 
287     /**
288      * Determines the minimum weights for the grid rows.
289      */
290     public double rowWeights[];
291 
292     protected static final int INITGRIDSIZE = 16;
293     protected static final int MINSIZE = 1;
294     protected static final int PREFERREDSIZE = 2;
295     protected static final int TINYSIZE = 3;
296 
297     protected Hashtable comptable;
298     protected GBConstraints defaultConstraints;
299     protected GBLayoutInfo layoutInfo;
300 
301     protected int anchor;
302     protected int clipAnchor;
303 
304     private static boolean layoutDisabled = false;
305     private static int disableCount = 0;
306     private static Insets windowInsets = new Insets(0, 0, 0, 0);
307 
308     /**
309      * Globally enable gridbag layout.  The
310      * default is for gridbag layout to
311      * be enabled.
312      */
enable()313     public synchronized static void enable() {
314         disableCount--;
315         if (disableCount <= 0)
316             layoutDisabled = false;
317     }
318 
319     /**
320      * Globally disable gridbag layout.  This can be used to improve
321      * performance by temporarily disabling layout during
322      * spurious calls to validate.
323      */
disable()324     public synchronized static void disable() {
325         disableCount++;
326         if (disableCount > 0)
327             layoutDisabled = true;
328     }
329 
330     /**
331      * Set the window insets.  The window insets default to (0,0,0,0).
332      */
setWindowInsets(Insets insets)333     public synchronized static void setWindowInsets(Insets insets) {
334         if (insets == null)
335             windowInsets = new Insets(0, 0, 0, 0);
336         else
337             windowInsets = (Insets)insets.clone();
338     }
339 
340     /**
341      * Get the window insets.
342      */
getWindowInsets()343     public synchronized static Insets getWindowInsets() {
344         return (Insets)windowInsets.clone();
345     }
346 
347     /**
348      * Creates a gridbag layout.
349      */
GBLayout()350     public GBLayout() {
351         comptable = new Hashtable();
352         defaultConstraints = new GBConstraints();
353 
354         anchor = GBConstraints.CENTER;
355         clipAnchor = GBConstraints.NORTHWEST;
356     }
357 
358     /**
359      * Sets the constraints for the specified component.
360      * @param comp the component to be modified
361      * @param constraints the constraints to be applied
362      */
setConstraints(Component comp, GBConstraints constraints)363     public void setConstraints(Component comp,
364 			       GBConstraints constraints) {
365         GBConstraints c = (GBConstraints)constraints.clone();
366         if (c.insets == null)
367             c.insets = new Insets(0, 0, 0, 0);
368         if (c.hardinsets == null)
369             c.hardinsets = new Insets(0, 0, 0, 0);
370 
371         comptable.put(comp, c);
372     }
373 
374     /**
375      * Sets the constraints from an option string.
376      * Each option has the form key=value. Options are separated by
377      * semicolons (;).
378      * @param comp the component to be modified
379      * @param constraints the constraints string
380      */
setConstraints(Component comp, String constraints)381     public void setConstraints(Component comp, String constraints) {
382         if (constraints == null)
383             return;
384 
385         comptable.put(comp, new GBConstraints(constraints));
386     }
387 
388     /**
389      * Retrieves the constraints for the specified component.  A copy of
390      * the constraints is returned.
391      * @param comp the component to be queried
392      */
getConstraints(Component comp)393     public GBConstraints getConstraints(Component comp) {
394         GBConstraints constraints = (GBConstraints)comptable.get(comp);
395         if (constraints == null) {
396             setConstraints(comp, defaultConstraints);
397             constraints = (GBConstraints)comptable.get(comp);
398         }
399         return (GBConstraints)constraints.clone();
400     }
401 
402     /**
403      * Retrieves the constraints for the specified
404      * component.  The return
405      * value is not a copy, but is the actual constraints
406      * class used by the
407      * layout mechanism.
408      * @param comp the component to be queried
409      */
lookupConstraints(Component comp)410     protected GBConstraints lookupConstraints(Component comp) {
411         GBConstraints constraints = (GBConstraints)comptable.get(comp);
412         if (constraints == null) {
413             setConstraints(comp, defaultConstraints);
414             constraints = (GBConstraints)comptable.get(comp);
415         }
416         return constraints;
417     }
418 
419     /**
420      * Returns the coordinates of the upper-left corner of the grid.
421      * The coordinates are based on the current layout of the grid.
422      */
getLayoutOrigin()423     public Point getLayoutOrigin() {
424         Point origin = new Point(0, 0);
425         if (layoutInfo != null) {
426             origin.x = layoutInfo.startx;
427             origin.y = layoutInfo.starty;
428         }
429         return origin;
430     }
431 
432     /**
433      * Returns the widths and heights of the grid columns and rows.
434      * The dimensions are based on the current layout of the grid.
435      */
getLayoutDimensions()436     public int [][] getLayoutDimensions() {
437         if (layoutInfo == null)
438             return new int[2][0];
439 
440         int dim[][] = new int [2][];
441         dim[0] = new int[layoutInfo.width];
442         dim[1] = new int[layoutInfo.height];
443 
444         System.arraycopy(layoutInfo.minWidth, 0, dim[0], 0,
445 			 layoutInfo.width);
446         System.arraycopy(layoutInfo.minHeight, 0, dim[1], 0,
447 			 layoutInfo.height);
448 
449         return dim;
450     }
451 
452     /**
453      * Returns the minimum widths and heights of the
454      * grid columns and rows.
455      * This is how the grid would be arranged if the parent were
456      * to be reshaped to its minimum size.
457      */
getMinimumLayoutDimensions(Container parent)458     public int [][] getMinimumLayoutDimensions(Container parent) {
459         GBLayoutInfo info = GetLayoutInfo(parent, MINSIZE);
460         int dim[][] = new int[2][];
461         dim[0] = new int[info.width];
462         dim[1] = new int[info.height];
463 
464         System.arraycopy(info.minWidth, 0, dim[0], 0, info.width);
465         System.arraycopy(info.minHeight, 0, dim[1], 0, info.height);
466 
467         return dim;
468     }
469 
470     /**
471      * Returns the preferred widths and heights of the
472      * grid columns and rows.
473      * This is how the grid would be arranged if the parent were
474      * to be reshaped to its preferred size.
475      */
getPreferredLayoutDimensions(Container parent)476     public int [][] getPreferredLayoutDimensions(Container parent) {
477         GBLayoutInfo info = GetLayoutInfo(parent, PREFERREDSIZE);
478         int dim[][] = new int[2][];
479         dim[0] = new int[info.width];
480         dim[1] = new int[info.height];
481 
482         System.arraycopy(info.minWidth, 0, dim[0], 0, info.width);
483         System.arraycopy(info.minHeight, 0, dim[1], 0, info.height);
484 
485         return dim;
486     }
487     /* BEGIN JSTYLED */
488     /**
489      * Returns the current set of weights for the grid
490      * columns and rows.
491      * The return value reflects the effective weights for the columns
492      * and rows after taking into account the weight constraints that
493      * are set on the child components.
494      */
495     /* END JSTYLED */
getLayoutWeights()496     public double [][] getLayoutWeights() {
497         if (layoutInfo == null)
498             return new double[2][0];
499 
500         double weights[][] = new double [2][];
501         weights[0] = new double[layoutInfo.width];
502         weights[1] = new double[layoutInfo.height];
503 
504         System.arraycopy(layoutInfo.weightX, 0, weights[0], 0,
505 			 layoutInfo.width);
506         System.arraycopy(layoutInfo.weightY, 0, weights[1], 0,
507 			 layoutInfo.height);
508 
509         return weights;
510     }
511 
512     /**
513      * Returns the coordinates of the grid cell corresponding
514      * to the given
515      * pixel coordinates.
516      */
location(int x, int y)517     public Point location(int x, int y) {
518         Point loc = new Point(0, 0);
519         int i, d;
520 
521         if (layoutInfo == null)
522             return loc;
523 
524         d = layoutInfo.startx;
525         for (i = 0; i < layoutInfo.width; i++) {
526             d += layoutInfo.minWidth[i];
527             if (d > x)
528                 break;
529         }
530         loc.x = i;
531 
532         d = layoutInfo.starty;
533         for (i = 0; i < layoutInfo.height; i++) {
534             d += layoutInfo.minHeight[i];
535             if (d > y)
536                 break;
537         }
538         loc.y = i;
539 
540         return loc;
541     }
542 
543     /**
544      * Sets the anchor for the gridbag.  The anchor determines
545      * the placement
546      * for the child components when the container
547      * has extra space and none
548      * of the children have weights.  The default anchor is CENTER.
549      */
setAnchor(int anchor)550     public void setAnchor(int anchor) {
551         this.anchor = anchor;
552     }
553 
554     /**
555      * Returns the current anchor.
556      */
getAnchor()557     public int getAnchor() {
558         return anchor;
559     }
560 
561     /**
562      * Sets the clip anchor.  The clip anchor determines
563      * which edge(s) of
564      * the container get clipped when there is not enough space.  The
565      * default clip anchor is NORTHWEST.  A clip anchor
566      * of NORTHWEST means
567      * that northwest corner is anchored, so the south
568      * and east edges will
569      * be clipped if there is not enough space.
570      */
setClipAnchor(int clipAnchor)571     public void setClipAnchor(int clipAnchor) {
572         this.clipAnchor = clipAnchor;
573     }
574 
575     /**
576      * Returns the current clip anchor.
577      */
getClipAnchor()578     public int getClipAnchor() {
579         return clipAnchor;
580     }
581 
582     /**
583      * If the parent is a Window, then adjust the insets according to
584      * the window insets.
585      */
getInsets(Container parent)586     private Insets getInsets(Container parent) {
587         Insets parentInsets = parent.insets();
588         Insets insets = null;
589         if (parentInsets != null) {
590             insets = (Insets) parentInsets.clone();
591         } else {
592             insets = new Insets(0, 0, 0, 0);
593         }
594         if (parent instanceof Window) {
595             insets.top += windowInsets.top;
596             insets.bottom += windowInsets.bottom;
597             insets.left += windowInsets.left;
598             insets.right += windowInsets.right;
599         }
600         return insets;
601     }
602 
603     /**
604      * Adds the specified component with the specified
605      * name to the layout.
606      * The name is converted to a set of GBConstraints.
607      * @param name the constraints string
608      * @param comp the component to be added
609      */
addLayoutComponent(String name, Component comp)610     public void addLayoutComponent(String name, Component comp) {
611         setConstraints(comp, name);
612     }
613 
614     /**
615      * Removes the specified component from the layout. Does not apply.
616      * @param comp the component to be removed
617      */
removeLayoutComponent(Component comp)618     public void removeLayoutComponent(Component comp) {
619     }
620 
621     /**
622      * Returns the preferred dimensions for this layout
623      * given the components
624      * in the specified panel.
625      * @param parent the component which needs to be laid out
626      * @see #minimumLayoutSize
627      */
preferredLayoutSize(Container parent)628     public Dimension preferredLayoutSize(Container parent) {
629         GBLayoutInfo info = GetLayoutInfo(parent, PREFERREDSIZE);
630         return GetMinSize(parent, info);
631     }
632 
633     /**
634      * Returns the minimum dimensions needed to layout the components
635      * contained in the specified panel.
636      * @param parent the component which needs to be laid out
637      * @see #preferredLayoutSize
638      */
minimumLayoutSize(Container parent)639     public Dimension minimumLayoutSize(Container parent) {
640         GBLayoutInfo info = GetLayoutInfo(parent, MINSIZE);
641         return GetMinSize(parent, info);
642     }
643 
644     /**
645      * Returns the smallest allowable size for the specified panel.
646      * This can be smaller than getMinimumSize if there are insets and
647      * pads set on any of the panel's children.
648      * @param parent the component which needs to be laid out
649      * @see #preferredLayoutSize
650      */
tinyLayoutSize(Container parent)651     public Dimension tinyLayoutSize(Container parent) {
652         GBLayoutInfo info = GetLayoutInfo(parent, TINYSIZE);
653         return GetMinSize(parent, info);
654     }
655 
656     /**
657      * Lays out the container in the specified panel.
658      * @param parent the specified component being laid out
659      * @see Container
660      */
layoutContainer(Container parent)661     public void layoutContainer(Container parent) {
662         if (!layoutDisabled)
663             ArrangeGrid(parent, true);
664     }
665 
666     /**
667      * Does everything that layout normally does, except the components
668      * aren't actually reshaped.  This has the useful side effect of
669      * setting the location and size variables in the constraints
670      * for each component.
671      * @param parent the specified component being laid out
672      * @see Container
673      */
layoutContainerNoReshape(Container parent)674     public void layoutContainerNoReshape(Container parent) {
675         if (!layoutDisabled)
676             ArrangeGrid(parent, false);
677     }
678 
679     /**
680      * Returns the String representation of this GBLayout's values.
681      */
toString()682     public String toString() {
683         return getClass().getName();
684     }
685     /* BEGIN JSTYLED */
686     /**
687      * Print the layout information.  Useful for debugging.
688      */
689 
690     /* DEBUG
691      *
692      *  protected void DumpLayoutInfo(GBLayoutInfo s) {
693      *    int x;
694      *
695      *    System.out.println("Col\tWidth\tWeight");
696      *    for (x=0; x<s.width; x++) {
697      *      System.out.println(x + "\t" +
698      *			 s.minWidth[x] + "\t" +
699      *			 s.weightX[x]);
700      *    }
701      *    System.out.println("Row\tHeight\tWeight");
702      *    for (x=0; x<s.height; x++) {
703      *      System.out.println(x + "\t" +
704      *			 s.minHeight[x] + "\t" +
705      *			 s.weightY[x]);
706      *    }
707      *  }
708      */
709 
710     /**
711      * Print the layout constraints.  Useful for debugging.
712      */
713 
714     /* DEBUG
715      *
716      *  protected void DumpConstraints(GBConstraints constraints) {
717      *    System.out.println(
718      *		       "wt " +
719      *		       constraints.weightx +
720      *		       " " +
721      *		       constraints.weighty +
722      *		       ", " +
723      *
724      *		       "box " +
725      *		       constraints.gridx +
726      *		       " " +
727      *		       constraints.gridy +
728      *		       " " +
729      *		       constraints.gridwidth +
730      *		       " " +
731      *		       constraints.gridheight +
732      *		       ", " +
733      *
734      *		       "min " +
735      *		       constraints.minWidth +
736      *		       " " +
737      *		       constraints.minHeight +
738      *		       ", " +
739      *
740      *		       "pad " +
741      *		       constraints.insets.bottom +
742      *		       " " +
743      *		       constraints.insets.left +
744      *		       " " +
745      *		       constraints.insets.right +
746      *		       " " +
747      *		       constraints.insets.top +
748      *		       " " +
749      *		       constraints.ipadx +
750      *		       " " +
751      *		       constraints.ipady);
752      *  }
753      */
754 
755     /**
756      * Fill in an instance of the GBLayoutInfo structure for the
757      * current set of managed children.  This requires four passes
758      * through the child components:
759      *<pre>
760      * 1) Figure out the dimensions of the layout grid.
761      * 2) Determine which cells the components occupy.
762      * 3) Distribute the weights among the rows/columns.
763      * 4) Distribute the minimum sizes among the rows/columns.
764      *</pre>
765      * This also caches the minsizes for all the children when they are
766      * first encountered (so subsequent loops don't need to ask again).
767      */
768 
769     /* END JSTYLED */
GetLayoutInfo(Container parent, int sizeflag)770     protected GBLayoutInfo GetLayoutInfo(Container parent,
771 					 int sizeflag) {
772         Component comp;
773         GBConstraints constraints;
774         Dimension d;
775         Component components[] = parent.getComponents();
776 
777         int compindex, width, height, i, j, k, px, py;
778         int limit, pixels_diff, nextSize;
779         int curX, curY, curWidth, curHeight, curRow, curCol;
780         double weight_diff, weight, start, size;
781         int xMax[], yMax[];
782 
783 	/* BEGIN JSTYLED */
784 	/*
785 	 * Pass #1
786 	 *
787 	 * Figure out the dimensions of the layout
788 	 * grid (use a value of 1 for
789 	 * zero or negative widths and heights).
790 	 */
791 	/* END JSTYLED */
792 
793         width = height = 0;
794         curRow = curCol = -1;
795         xMax = new int[INITGRIDSIZE];
796         yMax = new int[INITGRIDSIZE];
797 
798         for (compindex = 0; compindex < components.length; compindex++) {
799             comp = components[compindex];
800             if (!comp.isVisible())
801                 continue;
802             constraints = lookupConstraints(comp);
803 
804             curX = constraints.gridx;
805             curY = constraints.gridy;
806             curWidth = constraints.gridwidth;
807             if (curWidth <= 0)
808                 curWidth = 1;
809             curHeight = constraints.gridheight;
810             if (curHeight <= 0)
811                 curHeight = 1;
812 
813             /* If x or y is negative, then use relative positioning: */
814             if (curX < 0 && curY < 0) {
815                 if (curRow >= 0)
816                     curY = curRow;
817                 else if (curCol >= 0)
818                     curX = curCol;
819                 else
820                     curY = 0;
821             }
822             if (curX < 0) {
823                 px = 0;
824                 limit = curY + curHeight;
825                 xMax = ensureCapacity(xMax, limit);
826                 for (i = curY; i < limit; i++)
827                     px = Math.max(px, xMax[i]);
828 
829                 curX = px - curX - 1;
830                 if (curX < 0)
831                     curX = 0;
832             } else if (curY < 0) {
833                 py = 0;
834                 limit = curX + curWidth;
835                 yMax = ensureCapacity(yMax, limit);
836                 for (i = curX; i < limit; i++)
837                     py = Math.max(py, yMax[i]);
838 
839                 curY = py - curY - 1;
840                 if (curY < 0)
841                     curY = 0;
842             }
843 
844             /* Adjust the grid width and height */
845             for (px = curX + curWidth; width < px; width++);
846             for (py = curY + curHeight; height < py; height++);
847 
848             /* Adjust the xMax and yMax arrays */
849             yMax = ensureCapacity(yMax, px);
850             xMax = ensureCapacity(xMax, py);
851             for (i = curX; i < px; i++) { yMax[i] = py; }
852             for (i = curY; i < py; i++) { xMax[i] = px; }
853 
854             /* Cache the current slave's size. */
855             if (sizeflag == TINYSIZE) {
856                 if (comp instanceof Container) {
857                     Container cntr = (Container)comp;
858                     if (cntr.getLayout() instanceof GBLayout)
859                         d = ((GBLayout)cntr.getLayout()).tinyLayoutSize(cntr);
860                     else
861                         d = comp.getMinimumSize();
862                 }
863                 else
864                     d = comp.getMinimumSize();
865 
866                 constraints.tinyWidth = d.width;
867                 constraints.tinyHeight = d.height;
868 
869                 if (constraints.shrinkx)
870                     constraints.tinyWidth = 0;
871                 if (constraints.shrinky)
872                     constraints.tinyHeight = 0;
873 
874                 if (constraints.minsize == null) {
875                     d = comp.getMinimumSize();
876                     constraints.minsize = new Dimension(d.width,
877 							d.height);
878                 }
879             } else {
880                 if (sizeflag == PREFERREDSIZE) {
881                     d = comp.getPreferredSize();
882                     if (d.width <= 1 && d.height <= 1) {
883                         // If the preferred size is not reasonable
884                         // then try the minumum size
885                         d = comp.getMinimumSize();
886                         if (d.width <= 1 && d.height <= 1) {
887                             // Both preferred and minimun size
888                             // are small so use the actual size
889                             // that was set for the component.
890                             d = comp.getSize();
891                         }
892                     }
893                     constraints.minsize = new Dimension(d.width,
894 							d.height);
895                 } else {
896                     d = comp.getMinimumSize();
897                     // If the component is less than 1,1 minumum
898                     // size then
899                     // use getPreferredSize instead. This is
900                     // a workaround for
901                     // Beans that do not have getMinimumSize
902                     // implemented.
903                     if (d.width <= 1 && d.height <= 1) {
904                         d = comp.getPreferredSize();
905                         if (d.width <= 1 && d.height <= 1) {
906                             d = comp.getSize();
907                         }
908                     }
909                     constraints.minsize = new Dimension(d.width,
910 							d.height);
911                 }
912             }
913 	    /* BEGIN JSTYLED */
914 	    /*
915 	     * Zero width and height must mean that this is
916 	     * the last item (or
917 	     * else something is wrong).
918 	     */
919 	    if (constraints.gridheight == 0 &&
920 		constraints.gridwidth == 0)
921 		curRow = curCol = -1;
922 
923 	    /* Zero width starts a new row */
924 	    if (constraints.gridheight == 0 && curRow < 0)
925 		curCol = curX + curWidth;
926 
927 	    /* Zero height starts a new column */
928 	    else if (constraints.gridwidth == 0 && curCol < 0)
929 		curRow = curY + curHeight;
930 	}
931 
932 	/*
933 	 * Apply minimum row/column dimensions
934 	 */
935 	/* END JSTYLED */
936 	if (columnWidths != null && width < columnWidths.length)
937 	    width = columnWidths.length;
938 	if (rowHeights != null && height < rowHeights.length)
939 	    height = rowHeights.length;
940 
941 	GBLayoutInfo r = new GBLayoutInfo(width, height);
942 
943 	/*
944 	 * Pass #2
945 	 *
946 	 * Negative values for gridX are filled in with
947 	 * the current x value.
948 	 * Negative values for gridY are filled in with
949 	 * the current y value.
950 	 * Negative or zero values for gridWidth and
951 	 * gridHeight end the current
952 	 * row or column, respectively.
953 	 *
954 	 * Pass #1 figures out the grid dimensions.
955 	 * Pass #2 replaces the
956 	 * negative and zero values for gridWidth and gridHeight with
957 	 * real values that are based on the grid dimensions determined
958 	 * in pass #1.
959 	 */
960 
961 	curRow = curCol = -1;
962 	xMax = new int[height];
963 	yMax = new int[width];
964 
965 	for (compindex = 0; compindex < components.length;
966 	    compindex++) {
967 	    comp = components[compindex];
968 	    if (!comp.isVisible())
969 		continue;
970 	    constraints = lookupConstraints(comp);
971 
972 	    curX = constraints.gridx;
973 	    curY = constraints.gridy;
974 	    curWidth = constraints.gridwidth;
975 	    curHeight = constraints.gridheight;
976 
977 	    /* If x or y is negative, then use relative positioning: */
978 	    if (curX < 0 && curY < 0) {
979 		if (curRow >= 0)
980 		    curY = curRow;
981 		else if (curCol >= 0)
982 		    curX = curCol;
983 		else
984 		    curY = 0;
985 	    }
986 
987 	    if (curX < 0) {
988 		if (curHeight <= 0) {
989 		    curHeight += r.height - curY;
990 		    if (curHeight < 1)
991 			curHeight = 1;
992 		}
993 
994 		px = 0;
995 		for (i = curY; i < (curY + curHeight); i++)
996 		    px = Math.max(px, xMax[i]);
997 
998 		curX = px - curX - 1;
999 		if (curX < 0)
1000 		    curX = 0;
1001 	    } else if (curY < 0) {
1002 		if (curWidth <= 0) {
1003 		    curWidth += r.width - curX;
1004 		    if (curWidth < 1)
1005 			curWidth = 1;
1006 		}
1007 
1008 		py = 0;
1009 		for (i = curX; i < (curX + curWidth); i++)
1010 		    py = Math.max(py, yMax[i]);
1011 
1012 		curY = py - curY - 1;
1013 		if (curY < 0)
1014 		    curY = 0;
1015 	    }
1016 
1017 	    if (curWidth <= 0) {
1018 		curWidth += r.width - curX;
1019 		if (curWidth < 1)
1020 		    curWidth = 1;
1021 	    }
1022 
1023 	    if (curHeight <= 0) {
1024 		curHeight += r.height - curY;
1025 		if (curHeight < 1)
1026 		    curHeight = 1;
1027 	    }
1028 
1029 	    px = curX + curWidth;
1030 	    py = curY + curHeight;
1031 
1032 	    for (i = curX; i < px; i++) { yMax[i] = py; }
1033 	    for (i = curY; i < py; i++) { xMax[i] = px; }
1034 
1035 	    /* Make negative sizes start a new row/column */
1036 	    if (constraints.gridheight == 0 &&
1037                 constraints.gridwidth == 0)
1038                 curRow = curCol = -1;
1039 	    if (constraints.gridheight == 0 && curRow < 0)
1040 		curCol = curX + curWidth;
1041 	    else if (constraints.gridwidth == 0 && curCol < 0)
1042 		curRow = curY + curHeight;
1043 
1044 	    /* Assign the new values to the gridbag slave */
1045 	    constraints.tempX = curX;
1046 	    constraints.tempY = curY;
1047 	    constraints.tempWidth = curWidth;
1048 	    constraints.tempHeight = curHeight;
1049 	}
1050 
1051 	/*
1052 	 * Apply row/column weights.
1053 	 */
1054 
1055 	if (columnWeights != null)
1056 	    System.arraycopy(columnWeights, 0, r.weightX, 0,
1057 			     Math.min(columnWeights.length, r.weightX.length));
1058 	if (rowWeights != null)
1059 	    System.arraycopy(rowWeights, 0, r.weightY, 0,
1060 			     Math.min(rowWeights.length, r.weightY.length));
1061 
1062 	/*
1063 	 * Pass #3
1064 	 *
1065 	 * Distribute the weights.
1066 	 */
1067 
1068 	nextSize = Integer.MAX_VALUE;
1069 
1070 	for (i = 1;
1071 	    i != Integer.MAX_VALUE;
1072 	    i = nextSize, nextSize = Integer.MAX_VALUE) {
1073 	    for (compindex = 0; compindex < components.length;
1074 		 compindex++) {
1075 		comp = components[compindex];
1076 		if (!comp.isVisible())
1077 		    continue;
1078 		constraints = lookupConstraints(comp);
1079 
1080 		if (constraints.tempWidth == i) {
1081 		    px = constraints.tempX + constraints.tempWidth;
1082 		    /* right column */
1083 
1084 		    /*
1085 		     * Figure out if we should use this slave\'s
1086 		     * weight.  If the weight
1087 		     * is less than the total weight spanned
1088 		     * by the width of the cell,
1089 		     * then discard the weight.  Otherwise
1090 		     * split the difference
1091 		     * according to the existing weights.
1092 		     */
1093 
1094 		    weight_diff = constraints.weightx;
1095 		    for (k = constraints.tempX; k < px; k++)
1096 			weight_diff -= r.weightX[k];
1097 		    if (weight_diff > 0.0) {
1098 			weight = 0.0;
1099 			for (k = constraints.tempX; k < px; k++)
1100 			    weight += r.weightX[k];
1101 			for (k = constraints.tempX; weight > 0.0
1102 				 && k < px; k++) {
1103 			    double wt = r.weightX[k];
1104 			    double dx = (wt * weight_diff) / weight;
1105 			    r.weightX[k] += dx;
1106 			    weight_diff -= dx;
1107 			    weight -= wt;
1108 			}
1109 				/* BEGIN JSTYLED */
1110                                 /* Assign the remainder to the
1111 				 * rightmost cell */
1112 				/* END JSTYLED */
1113 			r.weightX[px-1] += weight_diff;
1114 		    }
1115 		} else if (constraints.tempWidth > i &&
1116 			   constraints.tempWidth < nextSize)
1117                     nextSize = constraints.tempWidth;
1118 
1119 
1120 		if (constraints.tempHeight == i) {
1121 		    py = constraints.tempY + constraints.tempHeight;
1122 		    /* bottom row */
1123 
1124 		    /*
1125 		     * Figure out if we should use this slave\'s
1126 		     * weight.  If the weight
1127 		     * is less than the total weight spanned by
1128 		     * the height of the cell,
1129 		     * then discard the weight.  Otherwise split
1130 		     * it the difference
1131 		     * according to the existing weights.
1132 		     */
1133 
1134 		    weight_diff = constraints.weighty;
1135 		    for (k = constraints.tempY; k < py; k++)
1136 			weight_diff -= r.weightY[k];
1137 		    if (weight_diff > 0.0) {
1138 			weight = 0.0;
1139 			for (k = constraints.tempY; k < py; k++)
1140 			    weight += r.weightY[k];
1141 			for (k = constraints.tempY; weight > 0.0
1142 				 && k < py; k++) {
1143 			    double wt = r.weightY[k];
1144 			    double dy = (wt * weight_diff) / weight;
1145 			    r.weightY[k] += dy;
1146 			    weight_diff -= dy;
1147 			    weight -= wt;
1148 			}
1149 			/* Assign the remainder to the bottom cell */
1150 			r.weightY[py-1] += weight_diff;
1151 		    }
1152 		} else if (constraints.tempHeight > i &&
1153 			   constraints.tempHeight < nextSize)
1154                     nextSize = constraints.tempHeight;
1155 	    }
1156 	}
1157 
1158 	/*
1159 	 * Apply minimum row/column widths.
1160 	 */
1161 
1162 	if (sizeflag == TINYSIZE) {
1163 	    if (columnWidths != null) {
1164 		for (i = 0; i < columnWidths.length; i++) {
1165 		    if (r.weightX[i] == 0)
1166 			r.minWidth[i] = columnWidths[i];
1167 		}
1168 	    }
1169 	    if (rowHeights != null) {
1170 		for (i = 0; i < rowHeights.length; i++) {
1171 		    if (r.weightY[i] == 0)
1172 			r.minHeight[i] = rowHeights[i];
1173 		}
1174 	    }
1175 	} else {
1176 	    if (columnWidths != null)
1177 		System.arraycopy(columnWidths, 0, r.minWidth, 0,
1178 				 columnWidths.length);
1179 	    if (rowHeights != null)
1180 		System.arraycopy(rowHeights, 0, r.minHeight, 0,
1181 				 rowHeights.length);
1182 	}
1183 
1184 	/*
1185 	 * Pass #4
1186 	 *
1187 	 * Distribute the minimum widths.
1188 	 */
1189 
1190 	nextSize = Integer.MAX_VALUE;
1191 
1192 	for (i = 1;
1193 	    i != Integer.MAX_VALUE;
1194 	    i = nextSize, nextSize = Integer.MAX_VALUE) {
1195 	    for (compindex = 0; compindex < components.length;
1196 		 compindex++) {
1197 		comp = components[compindex];
1198 		if (!comp.isVisible())
1199 		    continue;
1200 		constraints = lookupConstraints(comp);
1201 
1202 		if (constraints.tempWidth == i) {
1203 		    px = constraints.tempX + constraints.tempWidth;
1204 		    /* right column */
1205 
1206 		    /*
1207 		     * Calculate the minWidth array values.
1208 		     * First, figure out how wide the current
1209 		     * slave needs to be.
1210 		     * Then, see if it will fit within the
1211 		     * current minWidth values.
1212 		     * If it will not fit, add the difference
1213 		     * according to the
1214 		     * weightX array.
1215 		     */
1216 
1217 		    if (sizeflag == TINYSIZE && hasWeightX(r,
1218 							   constraints)) {
1219 			pixels_diff = constraints.tinyWidth
1220                             + constraints.hardipadx +
1221                             constraints.hardinsets.left +
1222                             constraints.hardinsets.right;
1223 		    } else {
1224 			pixels_diff = constraints.minsize.width +
1225                             constraints.ipadx + constraints.hardipadx +
1226                             constraints.insets.left +
1227                             constraints.insets.right +
1228                             constraints.hardinsets.left +
1229                             constraints.hardinsets.right;
1230 		    }
1231 
1232 		    for (k = constraints.tempX; k < px; k++)
1233 			pixels_diff -= r.minWidth[k];
1234 		    if (pixels_diff > 0) {
1235 			weight = 0.0;
1236 			for (k = constraints.tempX; k < px; k++)
1237 			    weight += r.weightX[k];
1238 			for (k = constraints.tempX; weight > 0.0 &&
1239 				 k < px; k++) {
1240 			    double wt = r.weightX[k];
1241 			    int dx = (int)((wt * ((double)
1242 						  pixels_diff)) / weight);
1243 			    r.minWidth[k] += dx;
1244 			    pixels_diff -= dx;
1245 			    weight -= wt;
1246 			}
1247 
1248 			/* Any leftovers are evenly distributed */
1249 			int dx = pixels_diff/(px-constraints.tempX);
1250 			for (k = constraints.tempX; k < (px-1); k++) {
1251 			    r.minWidth[k] += dx;
1252 			    pixels_diff -= dx;
1253 			}
1254 			r.minWidth[px-1] += pixels_diff;
1255 		    }
1256 		} else if (constraints.tempWidth > i &&
1257 			   constraints.tempWidth < nextSize)
1258                     nextSize = constraints.tempWidth;
1259 
1260 
1261 		if (constraints.tempHeight == i) {
1262 		    py = constraints.tempY + constraints.tempHeight;
1263 		    /* bottom row */
1264 
1265 		    /*
1266 		     * Calculate the minHeight array values.
1267 		     * First, figure out how tall the current
1268 		     * slave needs to be.
1269 		     * Then, see if it will fit within the
1270 		     * current minHeight values.
1271 		     * If it will not fit, add the difference
1272 		     * according to the
1273 		     * weightY array.
1274 		     */
1275 
1276 		    if (sizeflag == TINYSIZE && hasWeightY(r,
1277 							   constraints)) {
1278 			pixels_diff = constraints.tinyHeight +
1279                             constraints.hardipady +
1280                             constraints.hardinsets.top +
1281                             constraints.hardinsets.bottom;
1282 		    } else {
1283 			pixels_diff = constraints.minsize.height +
1284                             constraints.ipady + constraints.hardipady +
1285                             constraints.insets.top +
1286                             constraints.insets.bottom +
1287                             constraints.hardinsets.top +
1288                             constraints.hardinsets.bottom;
1289 		    }
1290 
1291 		    for (k = constraints.tempY; k < py; k++)
1292 			pixels_diff -= r.minHeight[k];
1293 		    if (pixels_diff > 0) {
1294 			weight = 0.0;
1295 			for (k = constraints.tempY; k < py; k++)
1296 			    weight += r.weightY[k];
1297 			for (k = constraints.tempY; weight > 0.0 &&
1298 				 k < py; k++) {
1299 			    double wt = r.weightY[k];
1300 			    int dy = (int)((wt * ((double)pixels_diff))
1301 					   / weight);
1302 			    r.minHeight[k] += dy;
1303 			    pixels_diff -= dy;
1304 			    weight -= wt;
1305 			}
1306 
1307 			/* Any leftovers are evenly distributed */
1308 			int dy = pixels_diff/(py-constraints.tempY);
1309 			for (k = constraints.tempY; k < (py-1); k++) {
1310 			    r.minHeight[k] += dy;
1311 			    pixels_diff -= dy;
1312 			}
1313 			r.minHeight[py-1] += pixels_diff;
1314 		    }
1315 		} else if (constraints.tempHeight > i &&
1316 			   constraints.tempHeight < nextSize)
1317                     nextSize = constraints.tempHeight;
1318 	    }
1319 	}
1320 
1321 	return r;
1322     }
1323 
ensureCapacity(int arr[], int size)1324     private int[] ensureCapacity(int arr[], int size) {
1325 	if (arr.length < size) {
1326 	    int newSize = arr.length * 2;
1327 	    if (newSize == 0)
1328 		newSize = 1;
1329 	    while (newSize < size)
1330 		newSize = newSize * 2;
1331 
1332 	    int newArr[] = new int[newSize];
1333 	    System.arraycopy(arr, 0, newArr, 0, arr.length);
1334 	    arr = newArr;
1335 	}
1336 
1337 	return arr;
1338     }
1339 
hasWeightX(GBLayoutInfo r, GBConstraints c)1340     private boolean hasWeightX(GBLayoutInfo r, GBConstraints c) {
1341 	int gx = c.tempX + c.tempWidth;
1342 	for (int i = c.tempX; i < gx; i++) {
1343 	    if (r.weightX[i] != 0)
1344 		return true;
1345 	}
1346 	return false;
1347     }
1348 
hasWeightY(GBLayoutInfo r, GBConstraints c)1349     private boolean hasWeightY(GBLayoutInfo r, GBConstraints c) {
1350 	int gy = c.tempY + c.tempHeight;
1351 	for (int i = c.tempY; i < gy; i++) {
1352 	    if (r.weightY[i] != 0)
1353 		return true;
1354 	}
1355 	return false;
1356     }
1357 
1358     /**
1359      * Adjusts the x, y, width, and height fields to the correct
1360      * values according to the constraint geometry and pads.
1361      */
AdjustForGravity(GBConstraints c, Rectangle r)1362     protected void AdjustForGravity(GBConstraints c, Rectangle r) {
1363 	int diffx, diffy, w, h;
1364 	Insets insets = (Insets)c.insets.clone();
1365 
1366 	w = r.width -
1367             (insets.left + insets.right + c.hardinsets.left +
1368 	    c.hardinsets.right);
1369 	h = r.height -
1370             (insets.top + insets.bottom + c.hardinsets.top +
1371 	    c.hardinsets.bottom);
1372 
1373 	if (w < c.tinyWidth) {
1374 	    if (c.fill == GBConstraints.HORIZONTAL ||
1375                 c.fill == GBConstraints.BOTH) {
1376 		diffx = c.tinyWidth - w;
1377 		insets.left -= diffx/2;
1378 		insets.right -= diffx/2;
1379 		if (insets.left < 0) {
1380 		    insets.right += insets.left;
1381 		    insets.left = 0;
1382 		}
1383 		if (insets.right < 0) {
1384 		    insets.left += insets.right;
1385 		    insets.right = 0;
1386 		}
1387 	    } else {
1388 		switch (c.anchor) {
1389 		case GBConstraints.NORTH:
1390 		case GBConstraints.SOUTH:
1391 		case GBConstraints.CENTER:
1392 		    diffx = c.tinyWidth - w;
1393 		    insets.left -= diffx/2;
1394 		    insets.right -= diffx/2;
1395 		    if (insets.left < 0) {
1396 			insets.right += insets.left;
1397 			insets.left = 0;
1398 		    }
1399 		    if (insets.right < 0) {
1400 			insets.left += insets.right;
1401 			insets.right = 0;
1402 		    }
1403 		    break;
1404 
1405 		case GBConstraints.NORTHWEST:
1406 		case GBConstraints.SOUTHWEST:
1407 		case GBConstraints.WEST:
1408 		    diffx = c.tinyWidth - w;
1409 		    insets.right -= diffx;
1410 		    if (insets.right < 0) {
1411 			insets.left += insets.right;
1412 			insets.right = 0;
1413 		    }
1414 		    break;
1415 
1416 		case GBConstraints.NORTHEAST:
1417 		case GBConstraints.SOUTHEAST:
1418 		case GBConstraints.EAST:
1419 		    diffx = c.tinyWidth - w;
1420 		    insets.left -= diffx;
1421 		    if (insets.left < 0) {
1422 			insets.right += insets.left;
1423 			insets.left = 0;
1424 		    }
1425 		    break;
1426 		default:
1427 		    /* JSTYLED */
1428 		    throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.4"));
1429 		}
1430 	    }
1431 	}
1432 
1433 	if (h < c.tinyHeight) {
1434 	    if (c.fill == GBConstraints.VERTICAL ||
1435                 c.fill == GBConstraints.BOTH) {
1436 		diffy = c.tinyHeight - h;
1437 		insets.top -= diffy/2;
1438 		insets.bottom -= diffy/2;
1439 		if (insets.top < 0) {
1440 		    insets.bottom += insets.top;
1441 		    insets.top = 0;
1442 		}
1443 		if (insets.bottom < 0) {
1444 		    insets.top += insets.bottom;
1445 		    insets.bottom = 0;
1446 		}
1447 	    } else {
1448 		switch (c.anchor) {
1449 		case GBConstraints.WEST:
1450 		case GBConstraints.EAST:
1451 		case GBConstraints.CENTER:
1452 		    diffy = c.tinyHeight - h;
1453 		    insets.top -= diffy/2;
1454 		    insets.bottom -= diffy/2;
1455 		    if (insets.top < 0) {
1456 			insets.bottom += insets.top;
1457 			insets.top = 0;
1458 		    }
1459 		    if (insets.bottom < 0) {
1460 			insets.top += insets.bottom;
1461 			insets.bottom = 0;
1462 		    }
1463 		    break;
1464 
1465 		case GBConstraints.NORTHWEST:
1466 		case GBConstraints.NORTHEAST:
1467 		case GBConstraints.NORTH:
1468 		    diffy = c.tinyHeight - h;
1469 		    insets.bottom -= diffy;
1470 		    if (insets.bottom < 0) {
1471 			insets.top += insets.bottom;
1472 			insets.bottom = 0;
1473 		    }
1474 		    break;
1475 
1476 		case GBConstraints.SOUTHWEST:
1477 		case GBConstraints.SOUTHEAST:
1478 		case GBConstraints.SOUTH:
1479 		    diffy = c.tinyHeight - h;
1480 		    insets.top -= diffy;
1481 		    if (insets.top < 0) {
1482 			insets.bottom += insets.top;
1483 			insets.top = 0;
1484 		    }
1485 		    break;
1486 		default:
1487 		    /* JSTYLED */
1488 		    throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.4"));
1489 		}
1490 	    }
1491 	}
1492 
1493 	r.x += insets.left + c.hardinsets.left;
1494 	r.width -= (insets.left + insets.right +
1495 		    c.hardinsets.left + c.hardinsets.right);
1496 	r.y += insets.top + c.hardinsets.top;
1497 	r.height -= (insets.top + insets.bottom +
1498 		     c.hardinsets.top + c.hardinsets.bottom);
1499 
1500 	diffx = 0;
1501 	if ((c.fill != GBConstraints.HORIZONTAL &&
1502 	    c.fill != GBConstraints.BOTH)
1503             && (r.width > (c.minsize.width + c.ipadx + c.hardipadx))) {
1504 	    diffx = r.width - (c.minsize.width + c.ipadx +
1505 			       c.hardipadx);
1506 	    r.width = c.minsize.width + c.ipadx + c.hardipadx;
1507 	}
1508 
1509 	diffy = 0;
1510 	if ((c.fill != GBConstraints.VERTICAL &&
1511 	    c.fill != GBConstraints.BOTH)
1512             && (r.height > (c.minsize.height + c.ipady + c.hardipady))) {
1513 	    diffy = r.height - (c.minsize.height + c.ipady +
1514 				c.hardipady);
1515 	    r.height = c.minsize.height + c.ipady + c.hardipady;
1516 	}
1517 
1518 	switch (c.anchor) {
1519 	case GBConstraints.CENTER:
1520 	    r.x += diffx/2;
1521 	    r.y += diffy/2;
1522 	    break;
1523 	case GBConstraints.NORTH:
1524 	    r.x += diffx/2;
1525 	    break;
1526 	case GBConstraints.NORTHEAST:
1527 	    r.x += diffx;
1528 	    break;
1529 	case GBConstraints.EAST:
1530 	    r.x += diffx;
1531 	    r.y += diffy/2;
1532 	    break;
1533 	case GBConstraints.SOUTHEAST:
1534 	    r.x += diffx;
1535 	    r.y += diffy;
1536 	    break;
1537 	case GBConstraints.SOUTH:
1538 	    r.x += diffx/2;
1539 	    r.y += diffy;
1540 	    break;
1541 	case GBConstraints.SOUTHWEST:
1542 	    r.y += diffy;
1543 	    break;
1544 	case GBConstraints.WEST:
1545 	    r.y += diffy/2;
1546 	    break;
1547 	case GBConstraints.NORTHWEST:
1548 	    break;
1549 	default:
1550 	    /* JSTYLED */
1551 	    throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.5"));
1552 	}
1553     }
1554 
1555     /**
1556      * Figure out the minimum size of the
1557      * parent based on the information retrieved from GetLayoutInfo.
1558      */
GetMinSize(Container parent, GBLayoutInfo info)1559     protected Dimension GetMinSize(Container parent,
1560 				   GBLayoutInfo info) {
1561 	Dimension d = new Dimension();
1562 	int i, t;
1563 	Insets insets = getInsets(parent);
1564 
1565 	t = 0;
1566 	for (i = 0; i < info.width; i++)
1567 	    t += info.minWidth[i];
1568 	d.width = t + insets.left + insets.right;
1569 
1570 	t = 0;
1571 	for (i = 0; i < info.height; i++)
1572 	    t += info.minHeight[i];
1573 	d.height = t + insets.top + insets.bottom;
1574 
1575 	return d;
1576     }
1577 
1578     /**
1579      * Lays out the grid.  Called directly from layoutContainer.
1580      */
ArrangeGrid(Container parent)1581     protected void ArrangeGrid(Container parent) {
1582 	ArrangeGrid(parent, true);
1583     }
1584 
1585     /**
1586      * Lays out the grid, conditionally reshaping the children.
1587      * The doReshape flag indicates whether or not
1588      * the children should be reshaped.
1589      *
1590      * @see layoutContainerNoReshape
1591      */
ArrangeGrid(Container parent, boolean doReshape)1592     protected void ArrangeGrid(Container parent, boolean doReshape) {
1593 	Component comp;
1594 	int compindex;
1595 	GBConstraints constraints;
1596 	Insets insets = getInsets(parent);
1597 	Component components[] = parent.getComponents();
1598 	Dimension d;
1599 	Rectangle r = new Rectangle();
1600 	int i, diffw, diffh;
1601 	double weight;
1602 	GBLayoutInfo info, tinyinfo;
1603 
1604 	/*
1605 	 * If the parent has no slaves anymore, then don't do anything
1606 	 * at all:  just leave the parent's size as-is.
1607 	 */
1608 	if (components.length == 0 &&
1609             (columnWidths == null || columnWidths.length == 0) &&
1610             (rowHeights == null || rowHeights.length == 0)) {
1611 	    return;
1612 	}
1613 
1614 	/*
1615 	 * Pass #1: scan all the slaves to figure out the total amount
1616 	 * of space needed.
1617 	 */
1618 
1619 	info = GetLayoutInfo(parent, PREFERREDSIZE);
1620 	d = GetMinSize(parent, info);
1621 
1622 	Dimension parentSize = parent.getSize();
1623 
1624 	if (d.width > parentSize.width || d.height >
1625             parentSize.height) {
1626 	    info = GetLayoutInfo(parent, MINSIZE);
1627 	    d = GetMinSize(parent, info);
1628 	}
1629 
1630 	tinyinfo = GetLayoutInfo(parent, TINYSIZE);
1631 
1632 	layoutInfo = info;
1633 	r.width = d.width;
1634 	r.height = d.height;
1635 
1636 	/* BEGIN JSTYLED */
1637 	/*
1638 	 * DEBUG
1639 	 *
1640 	 * DumpLayoutInfo(info);
1641 	 * for (compindex = 0 ; compindex < components.length ; compindex++) {
1642 	 * comp = components[compindex];
1643 	 * if (!comp.isVisible())
1644 	 *	continue;
1645 	 * constraints = lookupConstraints(comp);
1646 	 * DumpConstraints(constraints);
1647 	 * }
1648 	 * System.out.println("minSize " + r.width + " " + r.height);
1649 	 */
1650 
1651 	/*
1652 	 * If the current dimensions of the window don't match the desired
1653 	 * dimensions, then adjust the minWidth and minHeight arrays
1654 	 * according to the weights.
1655 	 */
1656 
1657 	/* END JSTYLED */
1658 
1659 	diffw = parentSize.width - r.width;
1660 	if (diffw != 0) {
1661 	    weight = 0.0;
1662 	    for (i = 0; i < info.width; i++)
1663 		weight += info.weightX[i];
1664 	    if (weight > 0.0) {
1665 		for (i = 0; i < info.width; i++) {
1666 		    int dx = (int)((((double)diffw) *
1667 				    info.weightX[i]) / weight);
1668 		    info.minWidth[i] += dx;
1669 		    r.width += dx;
1670 		    if (info.minWidth[i] < tinyinfo.minWidth[i]) {
1671 			r.width += tinyinfo.minWidth[i] -
1672                             info.minWidth[i];
1673 			info.minWidth[i] = tinyinfo.minWidth[i];
1674 		    }
1675 		}
1676 	    }
1677 	    diffw = parentSize.width - r.width;
1678 	} else {
1679 	    diffw = 0;
1680 	}
1681 
1682 	diffh = parentSize.height - r.height;
1683 	if (diffh != 0) {
1684 	    weight = 0.0;
1685 	    for (i = 0; i < info.height; i++)
1686 		weight += info.weightY[i];
1687 	    if (weight > 0.0) {
1688 		for (i = 0; i < info.height; i++) {
1689 		    int dy = (int)((((double)diffh) *
1690 				    info.weightY[i]) / weight);
1691 		    info.minHeight[i] += dy;
1692 		    r.height += dy;
1693 		    if (info.minHeight[i] < tinyinfo.minHeight[i]) {
1694 			r.height += tinyinfo.minHeight[i] -
1695                             info.minHeight[i];
1696 			info.minHeight[i] = tinyinfo.minHeight[i];
1697 		    }
1698 		}
1699 	    }
1700 	    diffh = parentSize.height - r.height;
1701 	} else {
1702 	    diffh = 0;
1703 	}
1704 
1705 	/*
1706 	 * DEBUG
1707 	 *
1708 	 * System.out.println("Re-adjusted:");
1709 	 * DumpLayoutInfo(info);
1710 	 */
1711 
1712 	/*
1713 	 * Now do the actual layout of the slaves
1714 	 * using the layout information
1715 	 * that has been collected.
1716 	 */
1717 
1718 	int anchorx = anchor;
1719 	int anchory = anchor;
1720 
1721 	if (diffw < 0)
1722 	    anchorx = clipAnchor;
1723 	if (diffh < 0)
1724 	    anchory = clipAnchor;
1725 
1726 	switch (anchorx) {
1727 	case GBConstraints.CENTER:
1728 	case GBConstraints.NORTH:
1729 	case GBConstraints.SOUTH:
1730 	    info.startx = diffw/2;
1731 	    break;
1732 
1733 	case GBConstraints.WEST:
1734 	case GBConstraints.NORTHWEST:
1735 	case GBConstraints.SOUTHWEST:
1736 	    info.startx = 0;
1737 	    break;
1738 
1739 	case GBConstraints.EAST:
1740 	case GBConstraints.NORTHEAST:
1741 	case GBConstraints.SOUTHEAST:
1742 	    info.startx = diffw;
1743 	    break;
1744 
1745 	default:
1746 	    /* JSTYLED */
1747 	    throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.6"));
1748 	}
1749 
1750 	switch (anchory) {
1751 	case GBConstraints.CENTER:
1752 	case GBConstraints.WEST:
1753 	case GBConstraints.EAST:
1754 	    info.starty = diffh/2;
1755 	    break;
1756 
1757 	case GBConstraints.NORTH:
1758 	case GBConstraints.NORTHWEST:
1759 	case GBConstraints.NORTHEAST:
1760 	    info.starty = 0;
1761 	    break;
1762 
1763 	case GBConstraints.SOUTH:
1764 	case GBConstraints.SOUTHWEST:
1765 	case GBConstraints.SOUTHEAST:
1766 	    info.starty = diffh;
1767 	    break;
1768 
1769 	default:
1770 	    /* JSTYLED */
1771 	    throw new IllegalArgumentException(Global.getMsg("sunsoft.jws.visual.rt.awt.GBLayout.illegal__anchor__value.7"));
1772 	}
1773 
1774 	info.startx += insets.left;
1775 	info.starty += insets.top;
1776 
1777 	for (compindex = 0; compindex < components.length;
1778 	    compindex++) {
1779 	    comp = components[compindex];
1780 	    if (!comp.isVisible())
1781 		continue;
1782 	    constraints = lookupConstraints(comp);
1783 
1784 	    r.x = info.startx;
1785 	    for (i = 0; i < constraints.tempX; i++)
1786 		r.x += info.minWidth[i];
1787 
1788 	    r.y = info.starty;
1789 	    for (i = 0; i < constraints.tempY; i++)
1790 		r.y += info.minHeight[i];
1791 
1792 	    r.width = 0;
1793 	    for (i = constraints.tempX;
1794 		 i < (constraints.tempX + constraints.tempWidth);
1795 		 i++) {
1796 		r.width += info.minWidth[i];
1797 	    }
1798 
1799 	    r.height = 0;
1800 	    for (i = constraints.tempY;
1801 		 i < (constraints.tempY + constraints.tempHeight);
1802 		 i++) {
1803 		r.height += info.minHeight[i];
1804 	    }
1805 
1806 	    AdjustForGravity(constraints, r);
1807 
1808 	    /*
1809 	     * If the window is too small to be interesting then
1810 	     * unmap it.  Otherwise configure it and then make sure
1811 	     * it's mapped.
1812 	     */
1813 
1814 	    if ((r.width <= 0) || (r.height <= 0)) {
1815 		if (doReshape)
1816 		    comp.reshape(-1, -1, 0, 0);
1817 		constraints.location = new Point(-1, -1);
1818 		constraints.size = new Dimension(0, 0);
1819 	    } else {
1820 		Point loc = comp.getLocation();
1821 		Dimension size = comp.getSize();
1822 
1823 		if (loc.x != r.x || loc.y != r.y ||
1824                     size.width != r.width || size.height != r.height) {
1825 		    if (doReshape)
1826 			comp.reshape(r.x, r.y, r.width, r.height);
1827 		    constraints.location = new Point(r.x, r.y);
1828 		    constraints.size = new Dimension(r.width, r.height);
1829 		}
1830 	    }
1831 	}
1832     }
1833 }
1834