KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > GridBagLayout


1 /*
2  * @(#)GridBagLayout.java 1.64 04/06/08
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7 package java.awt;
8
9 import java.util.Hashtable JavaDoc;
10 import java.util.Vector JavaDoc;
11
12 class GridBagLayoutInfo implements java.io.Serializable JavaDoc {
13   int width, height; /* number of cells horizontally, vertically */
14   int startx, starty; /* starting point for layout */
15   int minWidth[]; /* largest minWidth in each column */
16   int minHeight[]; /* largest minHeight in each row */
17   double weightX[]; /* largest weight in each column */
18   double weightY[]; /* largest weight in each row */
19
20   GridBagLayoutInfo () {
21       /* fix for 5055696 (avoiding AIOOBE by enlarging sizes) */
22       minWidth = new int[GridBagLayout.MAXGRIDSIZE];
23       minHeight = new int[GridBagLayout.MAXGRIDSIZE];
24       weightX = new double[GridBagLayout.MAXGRIDSIZE];
25       weightY = new double[GridBagLayout.MAXGRIDSIZE];
26   }
27 }
28
29 /**
30  * The <code>GridBagLayout</code> class is a flexible layout
31  * manager that aligns components vertically and horizontally,
32  * without requiring that the components be of the same size.
33  * Each <code>GridBagLayout</code> object maintains a dynamic,
34  * rectangular grid of cells, with each component occupying
35  * one or more cells, called its <em>display area</em>.
36  * <p>
37  * Each component managed by a <code>GridBagLayout</code> is associated with
38  * an instance of {@link GridBagConstraints}. The constraints object
39  * specifies where a component's display area should be located on the grid
40  * and how the component should be positioned within its display area. In
41  * addition to its constraints object, the <code>GridBagLayout</code> also
42  * considers each component's minimum and preferred sizes in order to
43  * determine a component's size.
44  * <p>
45  * The overall orientation of the grid depends on the container's
46  * {@link ComponentOrientation} property. For horizontal left-to-right
47  * orientations, grid coordinate (0,0) is in the upper left corner of the
48  * container with x increasing to the right and y increasing downward. For
49  * horizontal right-to-left orientations, grid coordinate (0,0) is in the upper
50  * right corner of the container with x increasing to the left and y
51  * increasing downward.
52  * <p>
53  * To use a grid bag layout effectively, you must customize one or more
54  * of the <code>GridBagConstraints</code> objects that are associated
55  * with its components. You customize a <code>GridBagConstraints</code>
56  * object by setting one or more of its instance variables:
57  * <p>
58  * <dl>
59  * <dt>{@link GridBagConstraints#gridx},
60  * {@link GridBagConstraints#gridy}
61  * <dd>Specifies the cell containing the leading corner of the component's
62  * display area, where the cell at the origin of the grid has address
63  * <code>gridx&nbsp;=&nbsp;0</code>,
64  * <code>gridy&nbsp;=&nbsp;0</code>. For horizontal left-to-right layout,
65  * a component's leading corner is its upper left. For horizontal
66  * right-to-left layout, a component's leading corner is its upper right.
67  * Use <code>GridBagConstraints.RELATIVE</code> (the default value)
68  * to specify that the component be placed immediately following
69  * (along the x axis for <code>gridx</code> or the y axis for
70  * <code>gridy</code>) the component that was added to the container
71  * just before this component was added.
72  * <dt>{@link GridBagConstraints#gridwidth},
73  * {@link GridBagConstraints#gridheight}
74  * <dd>Specifies the number of cells in a row (for <code>gridwidth</code>)
75  * or column (for <code>gridheight</code>)
76  * in the component's display area.
77  * The default value is 1.
78  * Use <code>GridBagConstraints.REMAINDER</code> to specify
79  * that the component's display area will be from <code>gridx</code>
80  * to the last cell in the row (for <code>gridwidth</code>)
81  * or from <code>gridy</code> to the last cell in the column
82  * (for <code>gridheight</code>).
83  *
84  * Use <code>GridBagConstraints.RELATIVE</code> to specify
85  * that the component's display area will be from <code>gridx</code>
86  * to the next to the last cell in its row (for <code>gridwidth</code>
87  * or from <code>gridy</code> to the next to the last cell in its
88  * column (for <code>gridheight</code>).
89  *
90  * <dt>{@link GridBagConstraints#fill}
91  * <dd>Used when the component's display area
92  * is larger than the component's requested size
93  * to determine whether (and how) to resize the component.
94  * Possible values are
95  * <code>GridBagConstraints.NONE</code> (the default),
96  * <code>GridBagConstraints.HORIZONTAL</code>
97  * (make the component wide enough to fill its display area
98  * horizontally, but don't change its height),
99  * <code>GridBagConstraints.VERTICAL</code>
100  * (make the component tall enough to fill its display area
101  * vertically, but don't change its width), and
102  * <code>GridBagConstraints.BOTH</code>
103  * (make the component fill its display area entirely).
104  * <dt>{@link GridBagConstraints#ipadx},
105  * {@link GridBagConstraints#ipady}
106  * <dd>Specifies the component's internal padding within the layout,
107  * how much to add to the minimum size of the component.
108  * The width of the component will be at least its minimum width
109  * plus <code>ipadx</code> pixels. Similarly, the height of
110  * the component will be at least the minimum height plus
111  * <code>ipady</code> pixels.
112  * <dt>{@link GridBagConstraints#insets}
113  * <dd>Specifies the component's external padding, the minimum
114  * amount of space between the component and the edges of its display area.
115  * <dt>{@link GridBagConstraints#anchor}
116  * <dd>Used when the component is smaller than its display area
117  * to determine where (within the display area) to place the component.
118  * There are two kinds of possible values: relative and absolute. Relative
119  * values are interpreted relative to the container's
120  * <code>ComponentOrientation</code> property while absolute values
121  * are not. Valid values are:</dd>
122  * <p>
123  * <center><table BORDER=0 COLS=2 WIDTH=800 SUMMARY="absolute and relative values as described above">
124  * <tr>
125  * <th><P ALIGN="LEFT">Absolute Values</th>
126  * <th><P ALIGN="LEFT">Relative Values</th>
127  * </tr>
128  * <tr>
129  * <td>
130  * <li><code>GridBagConstraints.NORTH</code></li>
131  * <li><code>GridBagConstraints.SOUTH</code></li>
132  * <li><code>GridBagConstraints.WEST</code></li>
133  * <li><code>GridBagConstraints.EAST</code></li>
134  * <li><code>GridBagConstraints.NORTHWEST</code></li>
135  * <li><code>GridBagConstraints.NORTHEAST</code></li>
136  * <li><code>GridBagConstraints.SOUTHWEST</code></li>
137  * <li><code>GridBagConstraints.SOUTHEAST</code></li>
138  * <li><code>GridBagConstraints.CENTER</code> (the default)</li>
139  * </td>
140  * <td>
141  * <li><code>GridBagConstraints.PAGE_START</code></li>
142  * <li><code>GridBagConstraints.PAGE_END</code></li>
143  * <li><code>GridBagConstraints.LINE_START</code></li>
144  * <li><code>GridBagConstraints.LINE_END</code></li>
145  * <li><code>GridBagConstraints.FIRST_LINE_START</code></li>
146  * <li><code>GridBagConstraints.FIRST_LINE_END</code></li>
147  * <li><code>GridBagConstraints.LAST_LINE_START</code></li>
148  * <li><code>GridBagConstraints.LAST_LINE_END</code></li>
149  * </ul>
150  * </td>
151  * </tr>
152  * </table></center><p>
153  * <dt>{@link GridBagConstraints#weightx},
154  * {@link GridBagConstraints#weighty}
155  * <dd>Used to determine how to distribute space, which is
156  * important for specifying resizing behavior.
157  * Unless you specify a weight for at least one component
158  * in a row (<code>weightx</code>) and column (<code>weighty</code>),
159  * all the components clump together in the center of their container.
160  * This is because when the weight is zero (the default),
161  * the <code>GridBagLayout</code> object puts any extra space
162  * between its grid of cells and the edges of the container.
163  * </dl>
164  * <p>
165  * The following figures show ten components (all buttons)
166  * managed by a grid bag layout. Figure 1 shows the layout for a horizontal,
167  * left-to-right container and Figure 2 shows the layout for a horizontal,
168  * right-to-left container.
169  * <p>
170  * <center><table COLS=2 WIDTH=600 summary="layout">
171  * <tr ALIGN=CENTER>
172  * <td>
173  * <img SRC="doc-files/GridBagLayout-1.gif" alt="The preceeding text describes this graphic (Figure 1)." ALIGN=center HSPACE=10 VSPACE=7>
174  * </td>
175  * <td>
176  * <img SRC="doc-files/GridBagLayout-2.gif" alt="The preceeding text describes this graphic (Figure 2)." ALIGN=center HSPACE=10 VSPACE=7>
177  * </td>
178  * <tr ALIGN=CENTER>
179  * <td>Figure 1: Horizontal, Left-to-Right</td>
180  * <td>Figure 2: Horizontal, Right-to-Left</td>
181  * </tr>
182  * </table></center>
183  * <p>
184  * Each of the ten components has the <code>fill</code> field
185  * of its associated <code>GridBagConstraints</code> object
186  * set to <code>GridBagConstraints.BOTH</code>.
187  * In addition, the components have the following non-default constraints:
188  * <p>
189  * <ul>
190  * <li>Button1, Button2, Button3: <code>weightx&nbsp;=&nbsp;1.0</code>
191  * <li>Button4: <code>weightx&nbsp;=&nbsp;1.0</code>,
192  * <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
193  * <li>Button5: <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
194  * <li>Button6: <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.RELATIVE</code>
195  * <li>Button7: <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
196  * <li>Button8: <code>gridheight&nbsp;=&nbsp;2</code>,
197  * <code>weighty&nbsp;=&nbsp;1.0</code>
198  * <li>Button9, Button 10:
199  * <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
200  * </ul>
201  * <p>
202  * Here is the code that implements the example shown above:
203  * <p>
204  * <hr><blockquote><pre>
205  * import java.awt.*;
206  * import java.util.*;
207  * import java.applet.Applet;
208  *
209  * public class GridBagEx1 extends Applet {
210  *
211  * protected void makebutton(String name,
212  * GridBagLayout gridbag,
213  * GridBagConstraints c) {
214  * Button button = new Button(name);
215  * gridbag.setConstraints(button, c);
216  * add(button);
217  * }
218  *
219  * public void init() {
220  * GridBagLayout gridbag = new GridBagLayout();
221  * GridBagConstraints c = new GridBagConstraints();
222  *
223  * setFont(new Font("SansSerif", Font.PLAIN, 14));
224  * setLayout(gridbag);
225  *
226  * c.fill = GridBagConstraints.BOTH;
227  * c.weightx = 1.0;
228  * makebutton("Button1", gridbag, c);
229  * makebutton("Button2", gridbag, c);
230  * makebutton("Button3", gridbag, c);
231  *
232  * c.gridwidth = GridBagConstraints.REMAINDER; //end row
233  * makebutton("Button4", gridbag, c);
234  *
235  * c.weightx = 0.0; //reset to the default
236  * makebutton("Button5", gridbag, c); //another row
237  *
238  * c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last in row
239  * makebutton("Button6", gridbag, c);
240  *
241  * c.gridwidth = GridBagConstraints.REMAINDER; //end row
242  * makebutton("Button7", gridbag, c);
243  *
244  * c.gridwidth = 1; //reset to the default
245  * c.gridheight = 2;
246  * c.weighty = 1.0;
247  * makebutton("Button8", gridbag, c);
248  *
249  * c.weighty = 0.0; //reset to the default
250  * c.gridwidth = GridBagConstraints.REMAINDER; //end row
251  * c.gridheight = 1; //reset to the default
252  * makebutton("Button9", gridbag, c);
253  * makebutton("Button10", gridbag, c);
254  *
255  * setSize(300, 100);
256  * }
257  *
258  * public static void main(String args[]) {
259  * Frame f = new Frame("GridBag Layout Example");
260  * GridBagEx1 ex1 = new GridBagEx1();
261  *
262  * ex1.init();
263  *
264  * f.add("Center", ex1);
265  * f.pack();
266  * f.setSize(f.getPreferredSize());
267  * f.show();
268  * }
269  * }
270  * </pre></blockquote><hr>
271  * <p>
272  * @version 1.64, 06/08/04
273  * @author Doug Stein
274  * @see java.awt.GridBagConstraints
275  * @see java.awt.ComponentOrientation
276  * @since JDK1.0
277  */

278 public class GridBagLayout implements LayoutManager2 JavaDoc,
279                       java.io.Serializable JavaDoc {
280
281     /* Maximum number of grid positions */
282   protected static final int MAXGRIDSIZE = 512;
283
284     /**
285      * The smallest grid that can be laid out by the grid bag layout.
286      */

287   protected static final int MINSIZE = 1;
288     /**
289      * The preferred grid size that can be laid out by the grid bag layout.
290      */

291   protected static final int PREFERREDSIZE = 2;
292
293     /**
294      * This hashtable maintains the association between
295      * a component and its gridbag constraints.
296      * The Keys in <code>comptable</code> are the components and the
297      * values are the instances of <code>GridBagConstraints</code>.
298      *
299      * @serial
300      * @see java.awt.GridBagConstraints
301      */

302   protected Hashtable JavaDoc<Component JavaDoc,GridBagConstraints JavaDoc> comptable;
303
304     /**
305      * This field holds a gridbag constraints instance
306      * containing the default values, so if a component
307      * does not have gridbag constraints associated with
308      * it, then the component will be assigned a
309      * copy of the <code>defaultConstraints</code>.
310      *
311      * @serial
312      * @see #getConstraints(Component)
313      * @see #setConstraints(Component, GridBagConstraints)
314      * @see #lookupConstraints(Component)
315      */

316   protected GridBagConstraints JavaDoc defaultConstraints;
317
318     /**
319      * This field holds the layout information
320      * for the gridbag. The information in this field
321      * is based on the most recent validation of the
322      * gridbag.
323      * If <code>layoutInfo</code> is <code>null</code>
324      * this indicates that there are no components in
325      * the gridbag or if there are components, they have
326      * not yet been validated.
327      *
328      * @serial
329      * @see #getLayoutInfo(Container, int)
330      */

331   protected GridBagLayoutInfo JavaDoc layoutInfo;
332
333     /**
334      * This field holds the overrides to the column minimum
335      * width. If this field is non-<code>null</code> the values are
336      * applied to the gridbag after all of the minimum columns
337      * widths have been calculated.
338      * If columnWidths has more elements than the number of
339      * columns, columns are added to the gridbag to match
340      * the number of elements in columnWidth.
341      *
342      * @serial
343      * @see #getLayoutDimensions()
344      */

345   public int columnWidths[];
346   
347    /**
348      * This field holds the overrides to the row minimum
349      * heights. If this field is non-</code>null</code> the values are
350      * applied to the gridbag after all of the minimum row
351      * heights have been calculated.
352      * If <code>rowHeights</code> has more elements than the number of
353      * rows, rowa are added to the gridbag to match
354      * the number of elements in <code>rowHeights</code>.
355      *
356      * @serial
357      * @see #getLayoutDimensions()
358      */

359   public int rowHeights[];
360
361     /**
362      * This field holds the overrides to the column weights.
363      * If this field is non-<code>null</code> the values are
364      * applied to the gridbag after all of the columns
365      * weights have been calculated.
366      * If <code>columnWeights[i]</code> &gt; weight for column i, then
367      * column i is assigned the weight in <code>columnWeights[i]</code>.
368      * If <code>columnWeights</code> has more elements than the number
369      * of columns, the excess elements are ignored - they do
370      * not cause more columns to be created.
371      *
372      * @serial
373      */

374   public double columnWeights[];
375
376     /**
377      * This field holds the overrides to the row weights.
378      * If this field is non-</code>null</code> the values are
379      * applied to the gridbag after all of the rows
380      * weights have been calculated.
381      * If <code>rowWeights[i]</code> &gt; weight for row i, then
382      * row i is assigned the weight in <code>rowWeights[i]</code>.
383      * If <code>rowWeights</code> has more elements than the number
384      * of rows, the excess elements are ignored - they do
385      * not cause more rows to be created.
386      *
387      * @serial
388      */

389   public double rowWeights[];
390
391   /**
392    * Creates a grid bag layout manager.
393    */

394   public GridBagLayout () {
395     comptable = new Hashtable JavaDoc<Component JavaDoc,GridBagConstraints JavaDoc>();
396     defaultConstraints = new GridBagConstraints JavaDoc();
397   }
398
399   /**
400    * Sets the constraints for the specified component in this layout.
401    * @param comp the component to be modified
402    * @param constraints the constraints to be applied
403    */

404   public void setConstraints(Component JavaDoc comp, GridBagConstraints JavaDoc constraints) {
405     comptable.put(comp, (GridBagConstraints JavaDoc)constraints.clone());
406   }
407
408   /**
409    * Gets the constraints for the specified component. A copy of
410    * the actual <code>GridBagConstraints</code> object is returned.
411    * @param comp the component to be queried
412    * @return the constraint for the specified component in this
413    * grid bag layout; a copy of the actual constraint
414    * object is returned
415    */

416   public GridBagConstraints JavaDoc getConstraints(Component JavaDoc comp) {
417     GridBagConstraints JavaDoc constraints = comptable.get(comp);
418     if (constraints == null) {
419       setConstraints(comp, defaultConstraints);
420       constraints = comptable.get(comp);
421     }
422     return (GridBagConstraints JavaDoc)constraints.clone();
423   }
424
425   /**
426    * Retrieves the constraints for the specified component.
427    * The return value is not a copy, but is the actual
428    * <code>GridBagConstraints</code> object used by the layout mechanism.
429    * <p>
430    * If <code>comp</code> is not in the <code>GridBagLayout</code>,
431    * a set of default <code>GridBagConstraints</code> are returned.
432    * A <code>comp</code> value of <code>null</code> is invalid
433    * and returns <code>null</code>.
434    *
435    * @param comp the component to be queried
436    * @return the contraints for the specified component
437    */

438   protected GridBagConstraints JavaDoc lookupConstraints(Component JavaDoc comp) {
439     GridBagConstraints JavaDoc constraints = comptable.get(comp);
440     if (constraints == null) {
441       setConstraints(comp, defaultConstraints);
442       constraints = comptable.get(comp);
443     }
444     return constraints;
445   }
446
447   /**
448    * Removes the constraints for the specified component in this layout
449    * @param comp the component to be modified
450    */

451   private void removeConstraints(Component JavaDoc comp) {
452     comptable.remove(comp);
453   }
454
455     /**
456      * Determines the origin of the layout area, in the graphics coordinate
457      * space of the target container. This value represents the pixel
458      * coordinates of the top-left corner of the layout area regardless of
459      * the <code>ComponentOrientation</code> value of the container. This
460      * is distinct from the grid origin given by the cell coordinates (0,0).
461      * Most applications do not call this method directly.
462      * @return the graphics origin of the cell in the top-left
463      * corner of the layout grid
464      * @see java.awt.ComponentOrientation
465      * @since JDK1.1
466      */

467   public Point JavaDoc getLayoutOrigin () {
468     Point JavaDoc origin = new Point JavaDoc(0,0);
469     if (layoutInfo != null) {
470       origin.x = layoutInfo.startx;
471       origin.y = layoutInfo.starty;
472     }
473     return origin;
474   }
475
476     /**
477      * Determines column widths and row heights for the layout grid.
478      * <p>
479      * Most applications do not call this method directly.
480      * @return an array of two arrays, containing the widths
481      * of the layout columns and
482      * the heights of the layout rows
483      * @since JDK1.1
484      */

485   public int [][] getLayoutDimensions () {
486     if (layoutInfo == null)
487       return new int[2][0];
488
489     int dim[][] = new int [2][];
490     dim[0] = new int[layoutInfo.width];
491     dim[1] = new int[layoutInfo.height];
492
493     System.arraycopy(layoutInfo.minWidth, 0, dim[0], 0, layoutInfo.width);
494     System.arraycopy(layoutInfo.minHeight, 0, dim[1], 0, layoutInfo.height);
495
496     return dim;
497   }
498
499     /**
500      * Determines the weights of the layout grid's columns and rows.
501      * Weights are used to calculate how much a given column or row
502      * stretches beyond its preferred size, if the layout has extra
503      * room to fill.
504      * <p>
505      * Most applications do not call this method directly.
506      * @return an array of two arrays, representing the
507      * horizontal weights of the layout columns
508      * and the vertical weights of the layout rows
509      * @since JDK1.1
510      */

511   public double [][] getLayoutWeights () {
512     if (layoutInfo == null)
513       return new double[2][0];
514
515     double weights[][] = new double [2][];
516     weights[0] = new double[layoutInfo.width];
517     weights[1] = new double[layoutInfo.height];
518
519     System.arraycopy(layoutInfo.weightX, 0, weights[0], 0, layoutInfo.width);
520     System.arraycopy(layoutInfo.weightY, 0, weights[1], 0, layoutInfo.height);
521
522     return weights;
523   }
524
525     /**
526      * Determines which cell in the layout grid contains the point
527      * specified by <code>(x,&nbsp;y)</code>. Each cell is identified
528      * by its column index (ranging from 0 to the number of columns
529      * minus 1) and its row index (ranging from 0 to the number of
530      * rows minus 1).
531      * <p>
532      * If the <code>(x,&nbsp;y)</code> point lies
533      * outside the grid, the following rules are used.
534      * The column index is returned as zero if <code>x</code> lies to the
535      * left of the layout for a left-to-right container or to the right of
536      * the layout for a right-to-left container. The column index is returned
537      * as the number of columns if <code>x</code> lies
538      * to the right of the layout in a left-to-right container or to the left
539      * in a right-to-left container.
540      * The row index is returned as zero if <code>y</code> lies above the
541      * layout, and as the number of rows if <code>y</code> lies
542      * below the layout. The orientation of a container is determined by its
543      * <code>ComponentOrientation</code> property.
544      * @param x the <i>x</i> coordinate of a point
545      * @param y the <i>y</i> coordinate of a point
546      * @return an ordered pair of indexes that indicate which cell
547      * in the layout grid contains the point
548      * (<i>x</i>,&nbsp;<i>y</i>).
549      * @see java.awt.ComponentOrientation
550      * @since JDK1.1
551      */

552   public Point JavaDoc location(int x, int y) {
553     Point JavaDoc loc = new Point JavaDoc(0,0);
554     int i, d;
555
556     if (layoutInfo == null)
557       return loc;
558
559     d = layoutInfo.startx;
560     if (!rightToLeft) {
561         for (i=0; i<layoutInfo.width; i++) {
562         d += layoutInfo.minWidth[i];
563         if (d > x)
564         break;
565     }
566     } else {
567         for (i=layoutInfo.width-1; i>=0; i--) {
568         if (d > x)
569         break;
570         d += layoutInfo.minWidth[i];
571     }
572     i++;
573     }
574     loc.x = i;
575
576     d = layoutInfo.starty;
577     for (i=0; i<layoutInfo.height; i++) {
578       d += layoutInfo.minHeight[i];
579       if (d > y)
580     break;
581     }
582     loc.y = i;
583
584     return loc;
585   }
586
587   /**
588    * Has no effect, since this layout manager does not use a per-component string.
589    */

590   public void addLayoutComponent(String JavaDoc name, Component JavaDoc comp) {
591   }
592
593     /**
594      * Adds the specified component to the layout, using the specified
595      * <code>constraints</code> object. Note that constraints
596      * are mutable and are, therefore, cloned when cached.
597      *
598      * @param comp the component to be added
599      * @param constraints an object that determines how
600      * the component is added to the layout
601      * @exception IllegalArgumentException if <code>constraints</code>
602      * is not a <code>GridBagConstraint</code>
603      */

604     public void addLayoutComponent(Component JavaDoc comp, Object JavaDoc constraints) {
605       if (constraints instanceof GridBagConstraints JavaDoc) {
606         setConstraints(comp, (GridBagConstraints JavaDoc)constraints);
607     } else if (constraints != null) {
608         throw new IllegalArgumentException JavaDoc("cannot add to layout: constraints must be a GridBagConstraint");
609     }
610     }
611
612   /**
613      * Removes the specified component from this layout.
614      * <p>
615      * Most applications do not call this method directly.
616      * @param comp the component to be removed.
617      * @see java.awt.Container#remove(java.awt.Component)
618      * @see java.awt.Container#removeAll()
619    */

620   public void removeLayoutComponent(Component JavaDoc comp) {
621     removeConstraints(comp);
622   }
623
624   /**
625     * Determines the preferred size of the <code>parent</code>
626     * container using this grid bag layout.
627     * <p>
628     * Most applications do not call this method directly.
629     *
630     * @param parent the container in which to do the layout
631     * @see java.awt.Container#getPreferredSize
632     * @return the preferred size of the <code>parent</code>
633     * container
634     */

635   public Dimension JavaDoc preferredLayoutSize(Container JavaDoc parent) {
636     GridBagLayoutInfo JavaDoc info = getLayoutInfo(parent, PREFERREDSIZE);
637     return getMinSize(parent, info);
638   }
639
640   /**
641     * Determines the minimum size of the <code>parent</code> container
642     * using this grid bag layout.
643     * <p>
644     * Most applications do not call this method directly.
645     * @param parent the container in which to do the layout
646     * @see java.awt.Container#doLayout
647     * @return the minimum size of the <code>parent</code> container
648     */

649   public Dimension JavaDoc minimumLayoutSize(Container JavaDoc parent) {
650     GridBagLayoutInfo JavaDoc info = getLayoutInfo(parent, MINSIZE);
651     return getMinSize(parent, info);
652   }
653
654     /**
655      * Returns the maximum dimensions for this layout given the components
656      * in the specified target container.
657      * @param target the container which needs to be laid out
658      * @see Container
659      * @see #minimumLayoutSize(Container)
660      * @see #preferredLayoutSize(Container)
661      * @return the maximum dimensions for this layout
662      */

663     public Dimension JavaDoc maximumLayoutSize(Container JavaDoc target) {
664     return new Dimension JavaDoc(Integer.MAX_VALUE, Integer.MAX_VALUE);
665     }
666
667     /**
668      * Returns the alignment along the x axis. This specifies how
669      * the component would like to be aligned relative to other
670      * components. The value should be a number between 0 and 1
671      * where 0 represents alignment along the origin, 1 is aligned
672      * the furthest away from the origin, 0.5 is centered, etc.
673      * <p>
674      * @return the value <code>0.5f</code> to indicate centered
675      */

676     public float getLayoutAlignmentX(Container JavaDoc parent) {
677     return 0.5f;
678     }
679
680     /**
681      * Returns the alignment along the y axis. This specifies how
682      * the component would like to be aligned relative to other
683      * components. The value should be a number between 0 and 1
684      * where 0 represents alignment along the origin, 1 is aligned
685      * the furthest away from the origin, 0.5 is centered, etc.
686      * <p>
687      * @return the value <code>0.5f</code> to indicate centered
688      */

689     public float getLayoutAlignmentY(Container JavaDoc parent) {
690     return 0.5f;
691     }
692
693     /**
694      * Invalidates the layout, indicating that if the layout manager
695      * has cached information it should be discarded.
696      */

697     public void invalidateLayout(Container JavaDoc target) {
698     }
699
700   /**
701    * Lays out the specified container using this grid bag layout.
702    * This method reshapes components in the specified container in
703    * order to satisfy the contraints of this <code>GridBagLayout</code>
704    * object.
705    * <p>
706    * Most applications do not call this method directly.
707    * @param parent the container in which to do the layout
708    * @see java.awt.Container
709    * @see java.awt.Container#doLayout
710    */

711   public void layoutContainer(Container JavaDoc parent) {
712     arrangeGrid(parent);
713   }
714
715   /**
716      * Returns a string representation of this grid bag layout's values.
717      * @return a string representation of this grid bag layout.
718    */

719   public String JavaDoc toString() {
720     return getClass().getName();
721   }
722
723   /**
724    * Print the layout information. Useful for debugging.
725    */

726
727   /* DEBUG
728    *
729    * protected void dumpLayoutInfo(GridBagLayoutInfo s) {
730    * int x;
731    *
732    * System.out.println("Col\tWidth\tWeight");
733    * for (x=0; x<s.width; x++) {
734    * System.out.println(x + "\t" +
735    * s.minWidth[x] + "\t" +
736    * s.weightX[x]);
737    * }
738    * System.out.println("Row\tHeight\tWeight");
739    * for (x=0; x<s.height; x++) {
740    * System.out.println(x + "\t" +
741    * s.minHeight[x] + "\t" +
742    * s.weightY[x]);
743    * }
744    * }
745    */

746
747   /**
748    * Print the layout constraints. Useful for debugging.
749    */

750
751   /* DEBUG
752    *
753    * protected void dumpConstraints(GridBagConstraints constraints) {
754    * System.out.println(
755    * "wt " +
756    * constraints.weightx +
757    * " " +
758    * constraints.weighty +
759    * ", " +
760    *
761    * "box " +
762    * constraints.gridx +
763    * " " +
764    * constraints.gridy +
765    * " " +
766    * constraints.gridwidth +
767    * " " +
768    * constraints.gridheight +
769    * ", " +
770    *
771    * "min " +
772    * constraints.minWidth +
773    * " " +
774    * constraints.minHeight +
775    * ", " +
776    *
777    * "pad " +
778    * constraints.insets.bottom +
779    * " " +
780    * constraints.insets.left +
781    * " " +
782    * constraints.insets.right +
783    * " " +
784    * constraints.insets.top +
785    * " " +
786    * constraints.ipadx +
787    * " " +
788    * constraints.ipady);
789    * }
790    */

791
792     /**
793      * Fills in an instance of <code>GridBagLayoutInfo</code> for the
794      * current set of managed children. This requires three passes through the
795      * set of children:
796      *
797      * <ol>
798      * <li>Figure out the dimensions of the layout grid.
799      * <li>Determine which cells the components occupy.
800      * <li>Distribute the weights and min sizes amoung the rows/columns.
801      * </ol>
802      *
803      * This also caches the minsizes for all the children when they are
804      * first encountered (so subsequent loops don't need to ask again).
805      * <p>
806      * This method should only be used internally by
807      * <code>GridBagLayout</code>.
808      *
809      * @param parent the layout container
810      * @param sizeflag either <code>PREFERREDSIZE</code> or
811      * <code>MINSIZE</code>
812      * @return the <code>GridBagLayoutInfo</code> for the set of children
813      * @since 1.4
814      */

815     protected GridBagLayoutInfo JavaDoc getLayoutInfo(Container JavaDoc parent, int sizeflag) {
816         return GetLayoutInfo(parent, sizeflag);
817     }
818
819     /**
820      * This method is obsolete and supplied for backwards
821      * compatability only; new code should call {@link
822      * #getLayoutInfo(java.awt.Container, int) getLayoutInfo} instead.
823      * This method is the same as <code>getLayoutInfo</code>;
824      * refer to <code>getLayoutInfo</code> for details on parameters
825      * and return value.
826      */

827   protected GridBagLayoutInfo JavaDoc GetLayoutInfo(Container JavaDoc parent, int sizeflag) {
828    synchronized (parent.getTreeLock()) {
829     GridBagLayoutInfo JavaDoc r = new GridBagLayoutInfo JavaDoc();
830     Component JavaDoc comp;
831     GridBagConstraints JavaDoc constraints;
832     Dimension JavaDoc d;
833     Component JavaDoc components[] = parent.getComponents();
834
835     int compindex, i, j, k, px, py, pixels_diff, nextSize;
836     int curX, curY, curWidth, curHeight, curRow, curCol;
837     double weight_diff, weight, start, size;
838     int xMax[], yMax[];
839
840     /*
841      * Pass #1
842      *
843      * Figure out the dimensions of the layout grid (use a value of 1 for
844      * zero or negative widths and heights).
845      */

846
847     r.width = r.height = 0;
848     curRow = curCol = -1;
849     xMax = new int[MAXGRIDSIZE];
850     yMax = new int[MAXGRIDSIZE];
851
852     for (compindex = 0 ; compindex < components.length ; compindex++) {
853       comp = components[compindex];
854       if (!comp.isVisible())
855     continue;
856       constraints = lookupConstraints(comp);
857
858       curX = constraints.gridx;
859       curY = constraints.gridy;
860       curWidth = constraints.gridwidth;
861       if (curWidth <= 0)
862     curWidth = 1;
863       curHeight = constraints.gridheight;
864       if (curHeight <= 0)
865     curHeight = 1;
866
867       /* If x or y is negative, then use relative positioning: */
868       if (curX < 0 && curY < 0) {
869     if (curRow >= 0)
870       curY = curRow;
871     else if (curCol >= 0)
872       curX = curCol;
873     else
874       curY = 0;
875       }
876       if (curX < 0) {
877     px = 0;
878         for (i = curY; i < (curY + curHeight); i++) {
879           px = Math.max(px, xMax[i]);
880         }
881
882     curX = px - curX - 1;
883     if(curX < 0)
884       curX = 0;
885       }
886       else if (curY < 0) {
887     py = 0;
888     for (i = curX; i < (curX + curWidth); i++) {
889         py = Math.max(py, yMax[i]);
890     }
891
892     curY = py - curY - 1;
893     if(curY < 0)
894       curY = 0;
895       }
896
897       /* Adjust the grid width and height */
898       for (px = curX + curWidth; r.width < px; r.width++);
899       for (py = curY + curHeight; r.height < py; r.height++);
900
901       /* Adjust xMax and yMax */
902       for (i = curX; i < (curX + curWidth); i++) {
903           yMax[i] = py;
904       }
905       for (i = curY; i < (curY + curHeight); i++) {
906           xMax[i] = px;
907       }
908
909       /* Cache the current slave's size. */
910       if (sizeflag == PREFERREDSIZE)
911     d = comp.getPreferredSize();
912       else
913     d = comp.getMinimumSize();
914       constraints.minWidth = d.width;
915       constraints.minHeight = d.height;
916
917       /* Zero width and height must mean that this is the last item (or
918        * else something is wrong). */

919       if (constraints.gridheight == 0 && constraints.gridwidth == 0)
920     curRow = curCol = -1;
921
922       /* Zero width starts a new row */
923       if (constraints.gridheight == 0 && curRow < 0)
924     curCol = curX + curWidth;
925
926       /* Zero height starts a new column */
927       else if (constraints.gridwidth == 0 && curCol < 0)
928     curRow = curY + curHeight;
929     }
930
931     /*
932      * Apply minimum row/column dimensions
933      */

934     if (columnWidths != null && r.width < columnWidths.length)
935         r.width = columnWidths.length;
936     if (rowHeights != null && r.height < rowHeights.length)
937         r.height = rowHeights.length;
938
939
940     /*
941      * Pass #2
942      *
943      * Negative values for gridX are filled in with the current x value.
944      * Negative values for gridY are filled in with the current y value.
945      * Negative or zero values for gridWidth and gridHeight end the current
946      * row or column, respectively.
947      */

948
949     curRow = curCol = -1;
950     xMax = new int[MAXGRIDSIZE];
951     yMax = new int[MAXGRIDSIZE];
952
953     for (compindex = 0 ; compindex < components.length ; compindex++) {
954       comp = components[compindex];
955       if (!comp.isVisible())
956     continue;
957       constraints = lookupConstraints(comp);
958
959       curX = constraints.gridx;
960       curY = constraints.gridy;
961       curWidth = constraints.gridwidth;
962       curHeight = constraints.gridheight;
963
964       /* If x or y is negative, then use relative positioning: */
965       if (curX < 0 && curY < 0) {
966     if(curRow >= 0)
967       curY = curRow;
968     else if(curCol >= 0)
969       curX = curCol;
970     else
971       curY = 0;
972       }
973
974       if (curX < 0) {
975     if (curHeight <= 0) {
976       curHeight += r.height - curY;
977       if (curHeight < 1)
978         curHeight = 1;
979     }
980
981     px = 0;
982     for (i = curY; i < (curY + curHeight); i++)
983       px = Math.max(px, xMax[i]);
984
985     curX = px - curX - 1;
986     if(curX < 0)
987       curX = 0;
988       }
989       else if (curY < 0) {
990     if (curWidth <= 0) {
991       curWidth += r.width - curX;
992       if (curWidth < 1)
993         curWidth = 1;
994     }
995
996     py = 0;
997     for (i = curX; i < (curX + curWidth); i++)
998       py = Math.max(py, yMax[i]);
999
1000    curY = py - curY - 1;
1001    if(curY < 0)
1002      curY = 0;
1003      }
1004
1005      if (curWidth <= 0) {
1006    curWidth += r.width - curX;
1007    if (curWidth < 1)
1008      curWidth = 1;
1009      }
1010
1011      if (curHeight <= 0) {
1012    curHeight += r.height - curY;
1013    if (curHeight < 1)
1014      curHeight = 1;
1015      }
1016
1017      px = curX + curWidth;
1018      py = curY + curHeight;
1019
1020      for (i = curX; i < (curX + curWidth); i++) { yMax[i] = py; }
1021      for (i = curY; i < (curY + curHeight); i++) { xMax[i] = px; }
1022
1023      /* Make negative sizes start a new row/column */
1024      if (constraints.gridheight == 0 && constraints.gridwidth == 0)
1025    curRow = curCol = -1;
1026      if (constraints.gridheight == 0 && curRow < 0)
1027    curCol = curX + curWidth;
1028      else if (constraints.gridwidth == 0 && curCol < 0)
1029        curRow = curY + curHeight;
1030
1031      /* Assign the new values to the gridbag slave */
1032      constraints.tempX = curX;
1033      constraints.tempY = curY;
1034      constraints.tempWidth = curWidth;
1035      constraints.tempHeight = curHeight;
1036    }
1037
1038    /*
1039     * Apply minimum row/column dimensions and weights
1040     */

1041    if (columnWidths != null)
1042      System.arraycopy(columnWidths, 0, r.minWidth, 0, columnWidths.length);
1043    if (rowHeights != null)
1044      System.arraycopy(rowHeights, 0, r.minHeight, 0, rowHeights.length);
1045    if (columnWeights != null)
1046      System.arraycopy(columnWeights, 0, r.weightX, 0, Math.min(r.weightX.length, columnWeights.length));
1047    if (rowWeights != null)
1048      System.arraycopy(rowWeights, 0, r.weightY, 0, Math.min(r.weightY.length, rowWeights.length));
1049
1050    /*
1051     * Pass #3
1052     *
1053     * Distribute the minimun widths and weights:
1054     */

1055
1056    nextSize = Integer.MAX_VALUE;
1057
1058    for (i = 1;
1059     i != Integer.MAX_VALUE;
1060     i = nextSize, nextSize = Integer.MAX_VALUE) {
1061      for (compindex = 0 ; compindex < components.length ; compindex++) {
1062    comp = components[compindex];
1063    if (!comp.isVisible())
1064      continue;
1065    constraints = lookupConstraints(comp);
1066
1067    if (constraints.tempWidth == i) {
1068      px = constraints.tempX + constraints.tempWidth; /* right column */
1069
1070      /*
1071       * Figure out if we should use this slave\'s weight. If the weight
1072       * is less than the total weight spanned by the width of the cell,
1073       * then discard the weight. Otherwise split the difference
1074       * according to the existing weights.
1075       */

1076
1077      weight_diff = constraints.weightx;
1078      for (k = constraints.tempX; k < px; k++)
1079        weight_diff -= r.weightX[k];
1080      if (weight_diff > 0.0) {
1081        weight = 0.0;
1082        for (k = constraints.tempX; k < px; k++)
1083          weight += r.weightX[k];
1084        for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
1085          double wt = r.weightX[k];
1086          double dx = (wt * weight_diff) / weight;
1087          r.weightX[k] += dx;
1088          weight_diff -= dx;
1089          weight -= wt;
1090        }
1091        /* Assign the remainder to the rightmost cell */
1092        r.weightX[px-1] += weight_diff;
1093      }
1094
1095      /*
1096       * Calculate the minWidth array values.
1097       * First, figure out how wide the current slave needs to be.
1098       * Then, see if it will fit within the current minWidth values.
1099       * If it will not fit, add the difference according to the
1100       * weightX array.
1101       */

1102
1103      pixels_diff =
1104        constraints.minWidth + constraints.ipadx +
1105        constraints.insets.left + constraints.insets.right;
1106
1107      for (k = constraints.tempX; k < px; k++)
1108        pixels_diff -= r.minWidth[k];
1109      if (pixels_diff > 0) {
1110        weight = 0.0;
1111        for (k = constraints.tempX; k < px; k++)
1112          weight += r.weightX[k];
1113        for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
1114          double wt = r.weightX[k];
1115          int dx = (int)((wt * ((double)pixels_diff)) / weight);
1116          r.minWidth[k] += dx;
1117          pixels_diff -= dx;
1118          weight -= wt;
1119        }
1120        /* Any leftovers go into the rightmost cell */
1121        r.minWidth[px-1] += pixels_diff;
1122      }
1123    }
1124    else if (constraints.tempWidth > i && constraints.tempWidth < nextSize)
1125      nextSize = constraints.tempWidth;
1126
1127
1128    if (constraints.tempHeight == i) {
1129      py = constraints.tempY + constraints.tempHeight; /* bottom row */
1130
1131      /*
1132       * Figure out if we should use this slave's weight. If the weight
1133       * is less than the total weight spanned by the height of the cell,
1134       * then discard the weight. Otherwise split it the difference
1135       * according to the existing weights.
1136       */

1137
1138      weight_diff = constraints.weighty;
1139      for (k = constraints.tempY; k < py; k++)
1140        weight_diff -= r.weightY[k];
1141      if (weight_diff > 0.0) {
1142        weight = 0.0;
1143        for (k = constraints.tempY; k < py; k++)
1144          weight += r.weightY[k];
1145        for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
1146          double wt = r.weightY[k];
1147          double dy = (wt * weight_diff) / weight;
1148          r.weightY[k] += dy;
1149          weight_diff -= dy;
1150          weight -= wt;
1151        }
1152        /* Assign the remainder to the bottom cell */
1153        r.weightY[py-1] += weight_diff;
1154      }
1155
1156      /*
1157       * Calculate the minHeight array values.
1158       * First, figure out how tall the current slave needs to be.
1159       * Then, see if it will fit within the current minHeight values.
1160       * If it will not fit, add the difference according to the
1161       * weightY array.
1162       */

1163
1164      pixels_diff =
1165        constraints.minHeight + constraints.ipady +
1166        constraints.insets.top + constraints.insets.bottom;
1167      for (k = constraints.tempY; k < py; k++)
1168        pixels_diff -= r.minHeight[k];
1169      if (pixels_diff > 0) {
1170        weight = 0.0;
1171        for (k = constraints.tempY; k < py; k++)
1172          weight += r.weightY[k];
1173        for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
1174          double wt = r.weightY[k];
1175          int dy = (int)((wt * ((double)pixels_diff)) / weight);
1176          r.minHeight[k] += dy;
1177          pixels_diff -= dy;
1178          weight -= wt;
1179        }
1180        /* Any leftovers go into the bottom cell */
1181        r.minHeight[py-1] += pixels_diff;
1182      }
1183    }
1184    else if (constraints.tempHeight > i &&
1185         constraints.tempHeight < nextSize)
1186      nextSize = constraints.tempHeight;
1187      }
1188    }
1189
1190    return r;
1191   }
1192  }
1193
1194    /**
1195     * Adjusts the x, y, width, and height fields to the correct
1196     * values depending on the constraint geometry and pads.
1197     * This method should only be used internally by
1198     * <code>GridBagLayout</code>.
1199     *
1200     * @param constraints the constraints to be applied
1201     * @param r the <code>Rectangle</code> to be adjusted
1202     * @since 1.4
1203     */

1204    protected void adjustForGravity(GridBagConstraints JavaDoc constraints,
1205        Rectangle JavaDoc r) {
1206        AdjustForGravity(constraints, r);
1207    }
1208
1209    /**
1210     * This method is obsolete and supplied for backwards
1211     * compatability only; new code should call {@link
1212     * #adjustForGravity(java.awt.GridBagConstraints, java.awt.Rectangle)
1213     * adjustForGravity} instead.
1214     * This method is the same as <code>adjustForGravity</code>;
1215     * refer to <code>adjustForGravity</code> for details
1216     * on parameters.
1217     */

1218  protected void AdjustForGravity(GridBagConstraints JavaDoc constraints,
1219                  Rectangle JavaDoc r) {
1220    int diffx, diffy;
1221
1222    if (!rightToLeft) {
1223    r.x += constraints.insets.left;
1224    } else {
1225    r.x -= r.width - constraints.insets.right;
1226    }
1227    r.width -= (constraints.insets.left + constraints.insets.right);
1228    r.y += constraints.insets.top;
1229    r.height -= (constraints.insets.top + constraints.insets.bottom);
1230
1231    diffx = 0;
1232    if ((constraints.fill != GridBagConstraints.HORIZONTAL &&
1233     constraints.fill != GridBagConstraints.BOTH)
1234    && (r.width > (constraints.minWidth + constraints.ipadx))) {
1235      diffx = r.width - (constraints.minWidth + constraints.ipadx);
1236      r.width = constraints.minWidth + constraints.ipadx;
1237    }
1238
1239    diffy = 0;
1240    if ((constraints.fill != GridBagConstraints.VERTICAL &&
1241     constraints.fill != GridBagConstraints.BOTH)
1242    && (r.height > (constraints.minHeight + constraints.ipady))) {
1243      diffy = r.height - (constraints.minHeight + constraints.ipady);
1244      r.height = constraints.minHeight + constraints.ipady;
1245    }
1246
1247    switch (constraints.anchor) {
1248    case GridBagConstraints.CENTER:
1249      r.x += diffx/2;
1250      r.y += diffy/2;
1251      break;
1252    case GridBagConstraints.PAGE_START:
1253    case GridBagConstraints.NORTH:
1254      r.x += diffx/2;
1255      break;
1256    case GridBagConstraints.NORTHEAST:
1257      r.x += diffx;
1258      break;
1259    case GridBagConstraints.EAST:
1260      r.x += diffx;
1261      r.y += diffy/2;
1262      break;
1263    case GridBagConstraints.SOUTHEAST:
1264      r.x += diffx;
1265      r.y += diffy;
1266      break;
1267    case GridBagConstraints.PAGE_END:
1268    case GridBagConstraints.SOUTH:
1269      r.x += diffx/2;
1270      r.y += diffy;
1271      break;
1272    case GridBagConstraints.SOUTHWEST:
1273      r.y += diffy;
1274      break;
1275    case GridBagConstraints.WEST:
1276      r.y += diffy/2;
1277      break;
1278    case GridBagConstraints.NORTHWEST:
1279      break;
1280    case GridBagConstraints.LINE_START:
1281      if (rightToLeft) {
1282        r.x += diffx;
1283      }
1284      r.y += diffy/2;
1285      break;
1286    case GridBagConstraints.LINE_END:
1287      if (!rightToLeft) {
1288        r.x += diffx;
1289      }
1290      r.y += diffy/2;
1291      break;
1292    case GridBagConstraints.FIRST_LINE_START:
1293      if (rightToLeft) {
1294        r.x += diffx;
1295      }
1296      break;
1297    case GridBagConstraints.FIRST_LINE_END:
1298      if (!rightToLeft) {
1299        r.x += diffx;
1300      }
1301      break;
1302    case GridBagConstraints.LAST_LINE_START:
1303      if (rightToLeft) {
1304        r.x += diffx;
1305      }
1306      r.y += diffy;
1307      break;
1308    case GridBagConstraints.LAST_LINE_END:
1309      if (!rightToLeft) {
1310        r.x += diffx;
1311      }
1312      r.y += diffy;
1313      break;
1314    default:
1315      throw new IllegalArgumentException JavaDoc("illegal anchor value");
1316    }
1317  }
1318
1319    /**
1320     * Figures out the minimum size of the
1321     * master based on the information from <code>getLayoutInfo</code>.
1322     * This method should only be used internally by
1323     * <code>GridBagLayout</code>.
1324     *
1325     * @param parent the layout container
1326     * @param info the layout info for this parent
1327     * @return a <code>Dimension</code> object containing the
1328     * minimum size
1329     * @since 1.4
1330     */

1331    protected Dimension JavaDoc getMinSize(Container JavaDoc parent, GridBagLayoutInfo JavaDoc info) {
1332        return GetMinSize(parent, info);
1333    }
1334
1335    /**
1336     * This method is obsolete and supplied for backwards
1337     * compatability only; new code should call {@link
1338     * #getMinSize(java.awt.Container, GridBagLayoutInfo) getMinSize} instead.
1339     * This method is the same as <code>getMinSize</code>;
1340     * refer to <code>getMinSize</code> for details on parameters
1341     * and return value.
1342     */

1343  protected Dimension JavaDoc GetMinSize(Container JavaDoc parent, GridBagLayoutInfo JavaDoc info) {
1344    Dimension JavaDoc d = new Dimension JavaDoc();
1345    int i, t;
1346    Insets JavaDoc insets = parent.getInsets();
1347
1348    t = 0;
1349    for(i = 0; i < info.width; i++)
1350      t += info.minWidth[i];
1351    d.width = t + insets.left + insets.right;
1352
1353    t = 0;
1354    for(i = 0; i < info.height; i++)
1355      t += info.minHeight[i];
1356    d.height = t + insets.top + insets.bottom;
1357
1358    return d;
1359  }
1360
1361    transient boolean rightToLeft = false;
1362
1363    /**
1364     * Lays out the grid.
1365     * This method should only be used internally by
1366     * <code>GridBagLayout</code>.
1367     *
1368     * @param parent the layout container
1369     * @since 1.4
1370     */

1371    protected void arrangeGrid(Container JavaDoc parent) {
1372        ArrangeGrid(parent);
1373    }
1374
1375    /**
1376     * This method is obsolete and supplied for backwards
1377     * compatability only; new code should call {@link
1378     * #arrangeGrid(Container) arrangeGrid} instead.
1379     * This method is the same as <code>arrangeGrid</code>;
1380     * refer to <code>arrangeGrid</code> for details on the
1381     * parameter.
1382     */

1383  protected void ArrangeGrid(Container JavaDoc parent) {
1384    Component JavaDoc comp;
1385    int compindex;
1386    GridBagConstraints JavaDoc constraints;
1387    Insets JavaDoc insets = parent.getInsets();
1388    Component JavaDoc components[] = parent.getComponents();
1389    Dimension JavaDoc d;
1390    Rectangle JavaDoc r = new Rectangle JavaDoc();
1391    int i, diffw, diffh;
1392    double weight;
1393    GridBagLayoutInfo JavaDoc info;
1394
1395    rightToLeft = !parent.getComponentOrientation().isLeftToRight();
1396
1397    /*
1398     * If the parent has no slaves anymore, then don't do anything
1399     * at all: just leave the parent's size as-is.
1400     */

1401    if (components.length == 0 &&
1402    (columnWidths == null || columnWidths.length == 0) &&
1403    (rowHeights == null || rowHeights.length == 0)) {
1404      return;
1405    }
1406
1407    /*
1408     * Pass #1: scan all the slaves to figure out the total amount
1409     * of space needed.
1410     */

1411
1412    info = getLayoutInfo(parent, PREFERREDSIZE);
1413    d = getMinSize(parent, info);
1414
1415    if (parent.width < d.width || parent.height < d.height) {
1416      info = getLayoutInfo(parent, MINSIZE);
1417      d = getMinSize(parent, info);
1418    }
1419
1420    layoutInfo = info;
1421    r.width = d.width;
1422    r.height = d.height;
1423
1424    /*
1425     * DEBUG
1426     *
1427     * DumpLayoutInfo(info);
1428     * for (compindex = 0 ; compindex < components.length ; compindex++) {
1429     * comp = components[compindex];
1430     * if (!comp.isVisible())
1431     * continue;
1432     * constraints = lookupConstraints(comp);
1433     * DumpConstraints(constraints);
1434     * }
1435     * System.out.println("minSize " + r.width + " " + r.height);
1436     */

1437
1438    /*
1439     * If the current dimensions of the window don't match the desired
1440     * dimensions, then adjust the minWidth and minHeight arrays
1441     * according to the weights.
1442     */

1443
1444    diffw = parent.width - r.width;
1445    if (diffw != 0) {
1446      weight = 0.0;
1447      for (i = 0; i < info.width; i++)
1448    weight += info.weightX[i];
1449      if (weight > 0.0) {
1450    for (i = 0; i < info.width; i++) {
1451      int dx = (int)(( ((double)diffw) * info.weightX[i]) / weight);
1452      info.minWidth[i] += dx;
1453      r.width += dx;
1454      if (info.minWidth[i] < 0) {
1455        r.width -= info.minWidth[i];
1456        info.minWidth[i] = 0;
1457      }
1458    }
1459      }
1460      diffw = parent.width - r.width;
1461    }
1462    
1463    else {
1464        diffw = 0;
1465    }
1466
1467    diffh = parent.height - r.height;
1468    if (diffh != 0) {
1469      weight = 0.0;
1470      for (i = 0; i < info.height; i++)
1471    weight += info.weightY[i];
1472      if (weight > 0.0) {
1473    for (i = 0; i < info.height; i++) {
1474      int dy = (int)(( ((double)diffh) * info.weightY[i]) / weight);
1475      info.minHeight[i] += dy;
1476      r.height += dy;
1477      if (info.minHeight[i] < 0) {
1478        r.height -= info.minHeight[i];
1479        info.minHeight[i] = 0;
1480      }
1481    }
1482      }
1483      diffh = parent.height - r.height;
1484    }
1485    
1486    else {
1487        diffh = 0;
1488    }
1489
1490    /*
1491     * DEBUG
1492     *
1493     * System.out.println("Re-adjusted:");
1494     * DumpLayoutInfo(info);
1495     */

1496
1497    /*
1498     * Now do the actual layout of the slaves using the layout information
1499     * that has been collected.
1500     */

1501
1502    info.startx = diffw/2 + insets.left;
1503    info.starty = diffh/2 + insets.top;
1504
1505    for (compindex = 0 ; compindex < components.length ; compindex++) {
1506      comp = components[compindex];
1507      if (!comp.isVisible())
1508    continue;
1509      constraints = lookupConstraints(comp);
1510
1511      if (!rightToLeft) {
1512        r.x = info.startx;
1513        for(i = 0; i < constraints.tempX; i++)
1514      r.x += info.minWidth[i];
1515      } else {
1516    r.x = parent.width - (diffw/2 + insets.right);
1517    for(i = 0; i < constraints.tempX; i++)
1518      r.x -= info.minWidth[i];
1519      }
1520
1521      r.y = info.starty;
1522      for(i = 0; i < constraints.tempY; i++)
1523    r.y += info.minHeight[i];
1524
1525      r.width = 0;
1526      for(i = constraints.tempX;
1527      i < (constraints.tempX + constraints.tempWidth);
1528      i++) {
1529    r.width += info.minWidth[i];
1530      }
1531
1532      r.height = 0;
1533      for(i = constraints.tempY;
1534      i < (constraints.tempY + constraints.tempHeight);
1535      i++) {
1536    r.height += info.minHeight[i];
1537      }
1538
1539      adjustForGravity(constraints, r);
1540
1541      /* fix for 4408108 - components were being created outside of the container */
1542      /* fix for 4969409 "-" replaced by "+" */
1543      if (r.x < 0) {
1544          r.width += r.x;
1545          r.x = 0;
1546      }
1547          
1548      if (r.y < 0) {
1549         r.height += r.y;
1550         r.y = 0;
1551      }
1552
1553      /*
1554       * If the window is too small to be interesting then
1555       * unmap it. Otherwise configure it and then make sure
1556       * it's mapped.
1557       */

1558
1559      if ((r.width <= 0) || (r.height <= 0)) {
1560    comp.setBounds(0, 0, 0, 0);
1561      }
1562      else {
1563    if (comp.x != r.x || comp.y != r.y ||
1564        comp.width != r.width || comp.height != r.height) {
1565      comp.setBounds(r.x, r.y, r.width, r.height);
1566    }
1567      }
1568    }
1569  }
1570
1571   // Added for serial backwards compatability (4348425)
1572
static final long serialVersionUID = 8838754796412211005L;
1573}
1574
Popular Tags