1 /*
   2  * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package java.awt;
  26 
  27 import java.util.Hashtable;
  28 import java.util.Arrays;
  29 
  30 /**
  31  * The <code>GridBagLayout</code> class is a flexible layout
  32  * manager that aligns components vertically, horizontally or along their
  33  * baseline without requiring that the components be of the same size.
  34  * Each <code>GridBagLayout</code> object maintains a dynamic,
  35  * rectangular grid of cells, with each component occupying
  36  * one or more cells, called its <em>display area</em>.
  37  * <p>
  38  * Each component managed by a <code>GridBagLayout</code> is associated with
  39  * an instance of {@link GridBagConstraints}.  The constraints object
  40  * specifies where a component's display area should be located on the grid
  41  * and how the component should be positioned within its display area.  In
  42  * addition to its constraints object, the <code>GridBagLayout</code> also
  43  * considers each component's minimum and preferred sizes in order to
  44  * determine a component's size.
  45  * <p>
  46  * The overall orientation of the grid depends on the container's
  47  * {@link ComponentOrientation} property.  For horizontal left-to-right
  48  * orientations, grid coordinate (0,0) is in the upper left corner of the
  49  * container with x increasing to the right and y increasing downward.  For
  50  * horizontal right-to-left orientations, grid coordinate (0,0) is in the upper
  51  * right corner of the container with x increasing to the left and y
  52  * increasing downward.
  53  * <p>
  54  * To use a grid bag layout effectively, you must customize one or more
  55  * of the <code>GridBagConstraints</code> objects that are associated
  56  * with its components. You customize a <code>GridBagConstraints</code>
  57  * object by setting one or more of its instance variables:
  58  * <p>
  59  * <dl>
  60  * <dt>{@link GridBagConstraints#gridx},
  61  * {@link GridBagConstraints#gridy}
  62  * <dd>Specifies the cell containing the leading corner of the component's
  63  * display area, where the cell at the origin of the grid has address
  64  * <code>gridx&nbsp;=&nbsp;0</code>,
  65  * <code>gridy&nbsp;=&nbsp;0</code>.  For horizontal left-to-right layout,
  66  * a component's leading corner is its upper left.  For horizontal
  67  * right-to-left layout, a component's leading corner is its upper right.
  68  * Use <code>GridBagConstraints.RELATIVE</code> (the default value)
  69  * to specify that the component be placed immediately following
  70  * (along the x axis for <code>gridx</code> or the y axis for
  71  * <code>gridy</code>) the component that was added to the container
  72  * just before this component was added.
  73  * <dt>{@link GridBagConstraints#gridwidth},
  74  * {@link GridBagConstraints#gridheight}
  75  * <dd>Specifies the number of cells in a row (for <code>gridwidth</code>)
  76  * or column (for <code>gridheight</code>)
  77  * in the component's display area.
  78  * The default value is 1.
  79  * Use <code>GridBagConstraints.REMAINDER</code> to specify
  80  * that the component's display area will be from <code>gridx</code>
  81  * to the last cell in the row (for <code>gridwidth</code>)
  82  * or from <code>gridy</code> to the last cell in the column
  83  * (for <code>gridheight</code>).
  84  *
  85  * Use <code>GridBagConstraints.RELATIVE</code> to specify
  86  * that the component's display area will be from <code>gridx</code>
  87  * to the next to the last cell in its row (for <code>gridwidth</code>
  88  * or from <code>gridy</code> to the next to the last cell in its
  89  * column (for <code>gridheight</code>).
  90  *
  91  * <dt>{@link GridBagConstraints#fill}
  92  * <dd>Used when the component's display area
  93  * is larger than the component's requested size
  94  * to determine whether (and how) to resize the component.
  95  * Possible values are
  96  * <code>GridBagConstraints.NONE</code> (the default),
  97  * <code>GridBagConstraints.HORIZONTAL</code>
  98  * (make the component wide enough to fill its display area
  99  * horizontally, but don't change its height),
 100  * <code>GridBagConstraints.VERTICAL</code>
 101  * (make the component tall enough to fill its display area
 102  * vertically, but don't change its width), and
 103  * <code>GridBagConstraints.BOTH</code>
 104  * (make the component fill its display area entirely).
 105  * <dt>{@link GridBagConstraints#ipadx},
 106  * {@link GridBagConstraints#ipady}
 107  * <dd>Specifies the component's internal padding within the layout,
 108  * how much to add to the minimum size of the component.
 109  * The width of the component will be at least its minimum width
 110  * plus <code>ipadx</code> pixels. Similarly, the height of
 111  * the component will be at least the minimum height plus
 112  * <code>ipady</code> pixels.
 113  * <dt>{@link GridBagConstraints#insets}
 114  * <dd>Specifies the component's external padding, the minimum
 115  * amount of space between the component and the edges of its display area.
 116  * <dt>{@link GridBagConstraints#anchor}
 117  * <dd>Specifies where the component should be positioned in its display area.
 118  * There are three kinds of possible values: absolute, orientation-relative,
 119  * and baseline-relative
 120  * Orientation relative values are interpreted relative to the container's
 121  * <code>ComponentOrientation</code> property while absolute values
 122  * are not.  Baseline relative values are calculated relative to the
 123  * baseline.  Valid values are:</dd>
 124  * <p>
 125  * <center><table BORDER=0 COLS=3 WIDTH=800
 126  *        SUMMARY="absolute, relative and baseline values as described above">
 127  * <tr>
 128  * <th><P ALIGN="LEFT">Absolute Values</th>
 129  * <th><P ALIGN="LEFT">Orientation Relative Values</th>
 130  * <th><P ALIGN="LEFT">Baseline Relative Values</th>
 131  * </tr>
 132  * <tr>
 133  * <td>
 134  * <li><code>GridBagConstraints.NORTH</code></li>
 135  * <li><code>GridBagConstraints.SOUTH</code></li>
 136  * <li><code>GridBagConstraints.WEST</code></li>
 137  * <li><code>GridBagConstraints.EAST</code></li>
 138  * <li><code>GridBagConstraints.NORTHWEST</code></li>
 139  * <li><code>GridBagConstraints.NORTHEAST</code></li>
 140  * <li><code>GridBagConstraints.SOUTHWEST</code></li>
 141  * <li><code>GridBagConstraints.SOUTHEAST</code></li>
 142  * <li><code>GridBagConstraints.CENTER</code> (the default)</li>
 143  * </td>
 144  * <td>
 145  * <li><code>GridBagConstraints.PAGE_START</code></li>
 146  * <li><code>GridBagConstraints.PAGE_END</code></li>
 147  * <li><code>GridBagConstraints.LINE_START</code></li>
 148  * <li><code>GridBagConstraints.LINE_END</code></li>
 149  * <li><code>GridBagConstraints.FIRST_LINE_START</code></li>
 150  * <li><code>GridBagConstraints.FIRST_LINE_END</code></li>
 151  * <li><code>GridBagConstraints.LAST_LINE_START</code></li>
 152  * <li><code>GridBagConstraints.LAST_LINE_END</code></li>
 153  * </td>
 154  * <td>
 155  * <li><code>GridBagConstraints.BASELINE</code></li>
 156  * <li><code>GridBagConstraints.BASELINE_LEADING</code></li>
 157  * <li><code>GridBagConstraints.BASELINE_TRAILING</code></li>
 158  * <li><code>GridBagConstraints.ABOVE_BASELINE</code></li>
 159  * <li><code>GridBagConstraints.ABOVE_BASELINE_LEADING</code></li>
 160  * <li><code>GridBagConstraints.ABOVE_BASELINE_TRAILING</code></li>
 161  * <li><code>GridBagConstraints.BELOW_BASELINE</code></li>
 162  * <li><code>GridBagConstraints.BELOW_BASELINE_LEADING</code></li>
 163  * <li><code>GridBagConstraints.BELOW_BASELINE_TRAILING</code></li>
 164  * </td>
 165  * </tr>
 166  * </table></center><p>
 167  * <dt>{@link GridBagConstraints#weightx},
 168  * {@link GridBagConstraints#weighty}
 169  * <dd>Used to determine how to distribute space, which is
 170  * important for specifying resizing behavior.
 171  * Unless you specify a weight for at least one component
 172  * in a row (<code>weightx</code>) and column (<code>weighty</code>),
 173  * all the components clump together in the center of their container.
 174  * This is because when the weight is zero (the default),
 175  * the <code>GridBagLayout</code> object puts any extra space
 176  * between its grid of cells and the edges of the container.
 177  * </dl>
 178  * <p>
 179  * Each row may have a baseline; the baseline is determined by the
 180  * components in that row that have a valid baseline and are aligned
 181  * along the baseline (the component's anchor value is one of {@code
 182  * BASELINE}, {@code BASELINE_LEADING} or {@code BASELINE_TRAILING}).
 183  * If none of the components in the row has a valid baseline, the row
 184  * does not have a baseline.
 185  * <p>
 186  * If a component spans rows it is aligned either to the baseline of
 187  * the start row (if the baseline-resize behavior is {@code
 188  * CONSTANT_ASCENT}) or the end row (if the baseline-resize behavior
 189  * is {@code CONSTANT_DESCENT}).  The row that the component is
 190  * aligned to is called the <em>prevailing row</em>.
 191  * <p>
 192  * The following figure shows a baseline layout and includes a
 193  * component that spans rows:
 194  * <center><table summary="Baseline Layout">
 195  * <tr ALIGN=CENTER>
 196  * <td>
 197  * <img src="doc-files/GridBagLayout-baseline.png"
 198  *  alt="The following text describes this graphic (Figure 1)." ALIGN=center>
 199  * </td>
 200  * </table></center>
 201  * This layout consists of three components:
 202  * <ul><li>A panel that starts in row 0 and ends in row 1.  The panel
 203  *   has a baseline-resize behavior of <code>CONSTANT_DESCENT</code> and has
 204  *   an anchor of <code>BASELINE</code>.  As the baseline-resize behavior
 205  *   is <code>CONSTANT_DESCENT</code> the prevailing row for the panel is
 206  *   row 1.
 207  * <li>Two buttons, each with a baseline-resize behavior of
 208  *   <code>CENTER_OFFSET</code> and an anchor of <code>BASELINE</code>.
 209  * </ul>
 210  * Because the second button and the panel share the same prevailing row,
 211  * they are both aligned along their baseline.
 212  * <p>
 213  * Components positioned using one of the baseline-relative values resize
 214  * differently than when positioned using an absolute or orientation-relative
 215  * value.  How components change is dictated by how the baseline of the
 216  * prevailing row changes.  The baseline is anchored to the
 217  * bottom of the display area if any components with the same prevailing row
 218  * have a baseline-resize behavior of <code>CONSTANT_DESCENT</code>,
 219  * otherwise the baseline is anchored to the top of the display area.
 220  * The following rules dictate the resize behavior:
 221  * <ul>
 222  * <li>Resizable components positioned above the baseline can only
 223  * grow as tall as the baseline.  For example, if the baseline is at 100
 224  * and anchored at the top, a resizable component positioned above the
 225  * baseline can never grow more than 100 units.
 226  * <li>Similarly, resizable components positioned below the baseline can
 227  * only grow as high as the difference between the display height and the
 228  * baseline.
 229  * <li>Resizable components positioned on the baseline with a
 230  * baseline-resize behavior of <code>OTHER</code> are only resized if
 231  * the baseline at the resized size fits within the display area.  If
 232  * the baseline is such that it does not fit within the display area
 233  * the component is not resized.
 234  * <li>Components positioned on the baseline that do not have a
 235  * baseline-resize behavior of <code>OTHER</code>
 236  * can only grow as tall as {@code display height - baseline + baseline of component}.
 237  * </ul>
 238  * If you position a component along the baseline, but the
 239  * component does not have a valid baseline, it will be vertically centered
 240  * in its space.  Similarly if you have positioned a component relative
 241  * to the baseline and none of the components in the row have a valid
 242  * baseline the component is vertically centered.
 243  * <p>
 244  * The following figures show ten components (all buttons)
 245  * managed by a grid bag layout.  Figure 2 shows the layout for a horizontal,
 246  * left-to-right container and Figure 3 shows the layout for a horizontal,
 247  * right-to-left container.
 248  * <p>
 249  * <center><table COLS=2 WIDTH=600 summary="layout">
 250  * <tr ALIGN=CENTER>
 251  * <td>
 252  * <img src="doc-files/GridBagLayout-1.gif" alt="The preceeding text describes this graphic (Figure 1)." ALIGN=center HSPACE=10 VSPACE=7>
 253  * </td>
 254  * <td>
 255  * <img src="doc-files/GridBagLayout-2.gif" alt="The preceeding text describes this graphic (Figure 2)." ALIGN=center HSPACE=10 VSPACE=7>
 256  * </td>
 257  * <tr ALIGN=CENTER>
 258  * <td>Figure 2: Horizontal, Left-to-Right</td>
 259  * <td>Figure 3: Horizontal, Right-to-Left</td>
 260  * </tr>
 261  * </table></center>
 262  * <p>
 263  * Each of the ten components has the <code>fill</code> field
 264  * of its associated <code>GridBagConstraints</code> object
 265  * set to <code>GridBagConstraints.BOTH</code>.
 266  * In addition, the components have the following non-default constraints:
 267  * <p>
 268  * <ul>
 269  * <li>Button1, Button2, Button3: <code>weightx&nbsp;=&nbsp;1.0</code>
 270  * <li>Button4: <code>weightx&nbsp;=&nbsp;1.0</code>,
 271  * <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
 272  * <li>Button5: <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
 273  * <li>Button6: <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.RELATIVE</code>
 274  * <li>Button7: <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
 275  * <li>Button8: <code>gridheight&nbsp;=&nbsp;2</code>,
 276  * <code>weighty&nbsp;=&nbsp;1.0</code>
 277  * <li>Button9, Button 10:
 278  * <code>gridwidth&nbsp;=&nbsp;GridBagConstraints.REMAINDER</code>
 279  * </ul>
 280  * <p>
 281  * Here is the code that implements the example shown above:
 282  * <p>
 283  * <hr><blockquote><pre>
 284  * import java.awt.*;
 285  * import java.util.*;
 286  * import java.applet.Applet;
 287  *
 288  * public class GridBagEx1 extends Applet {
 289  *
 290  *     protected void makebutton(String name,
 291  *                               GridBagLayout gridbag,
 292  *                               GridBagConstraints c) {
 293  *         Button button = new Button(name);
 294  *         gridbag.setConstraints(button, c);
 295  *         add(button);
 296  *     }
 297  *
 298  *     public void init() {
 299  *         GridBagLayout gridbag = new GridBagLayout();
 300  *         GridBagConstraints c = new GridBagConstraints();
 301  *
 302  *         setFont(new Font("SansSerif", Font.PLAIN, 14));
 303  *         setLayout(gridbag);
 304  *
 305  *         c.fill = GridBagConstraints.BOTH;
 306  *         c.weightx = 1.0;
 307  *         makebutton("Button1", gridbag, c);
 308  *         makebutton("Button2", gridbag, c);
 309  *         makebutton("Button3", gridbag, c);
 310  *
 311  *         c.gridwidth = GridBagConstraints.REMAINDER; //end row
 312  *         makebutton("Button4", gridbag, c);
 313  *
 314  *         c.weightx = 0.0;                //reset to the default
 315  *         makebutton("Button5", gridbag, c); //another row
 316  *
 317  *         c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last in row
 318  *         makebutton("Button6", gridbag, c);
 319  *
 320  *         c.gridwidth = GridBagConstraints.REMAINDER; //end row
 321  *         makebutton("Button7", gridbag, c);
 322  *
 323  *         c.gridwidth = 1;                //reset to the default
 324  *         c.gridheight = 2;
 325  *         c.weighty = 1.0;
 326  *         makebutton("Button8", gridbag, c);
 327  *
 328  *         c.weighty = 0.0;                //reset to the default
 329  *         c.gridwidth = GridBagConstraints.REMAINDER; //end row
 330  *         c.gridheight = 1;               //reset to the default
 331  *         makebutton("Button9", gridbag, c);
 332  *         makebutton("Button10", gridbag, c);
 333  *
 334  *         setSize(300, 100);
 335  *     }
 336  *
 337  *     public static void main(String args[]) {
 338  *         Frame f = new Frame("GridBag Layout Example");
 339  *         GridBagEx1 ex1 = new GridBagEx1();
 340  *
 341  *         ex1.init();
 342  *
 343  *         f.add("Center", ex1);
 344  *         f.pack();
 345  *         f.setSize(f.getPreferredSize());
 346  *         f.show();
 347  *     }
 348  * }
 349  * </pre></blockquote><hr>
 350  * <p>
 351  * @author Doug Stein
 352  * @author Bill Spitzak (orignial NeWS & OLIT implementation)
 353  * @see       java.awt.GridBagConstraints
 354  * @see       java.awt.GridBagLayoutInfo
 355  * @see       java.awt.ComponentOrientation
 356  * @since JDK1.0
 357  */
 358 public class GridBagLayout implements LayoutManager2,
 359 java.io.Serializable {
 360 
 361     static final int EMPIRICMULTIPLIER = 2;
 362     /**
 363      * This field is no longer used to reserve arrays and keeped for backward
 364      * compatibility. Previously, this was
 365      * the maximum number of grid positions (both horizontal and
 366      * vertical) that could be laid out by the grid bag layout.
 367      * Current implementation doesn't impose any limits
 368      * on the size of a grid.
 369      */
 370     protected static final int MAXGRIDSIZE = 512;
 371 
 372     /**
 373      * The smallest grid that can be laid out by the grid bag layout.
 374      */
 375     protected static final int MINSIZE = 1;
 376     /**
 377      * The preferred grid size that can be laid out by the grid bag layout.
 378      */
 379     protected static final int PREFERREDSIZE = 2;
 380 
 381     /**
 382      * This hashtable maintains the association between
 383      * a component and its gridbag constraints.
 384      * The Keys in <code>comptable</code> are the components and the
 385      * values are the instances of <code>GridBagConstraints</code>.
 386      *
 387      * @serial
 388      * @see java.awt.GridBagConstraints
 389      */
 390     protected Hashtable<Component,GridBagConstraints> comptable;
 391 
 392     /**
 393      * This field holds a gridbag constraints instance
 394      * containing the default values, so if a component
 395      * does not have gridbag constraints associated with
 396      * it, then the component will be assigned a
 397      * copy of the <code>defaultConstraints</code>.
 398      *
 399      * @serial
 400      * @see #getConstraints(Component)
 401      * @see #setConstraints(Component, GridBagConstraints)
 402      * @see #lookupConstraints(Component)
 403      */
 404     protected GridBagConstraints defaultConstraints;
 405 
 406     /**
 407      * This field holds the layout information
 408      * for the gridbag.  The information in this field
 409      * is based on the most recent validation of the
 410      * gridbag.
 411      * If <code>layoutInfo</code> is <code>null</code>
 412      * this indicates that there are no components in
 413      * the gridbag or if there are components, they have
 414      * not yet been validated.
 415      *
 416      * @serial
 417      * @see #getLayoutInfo(Container, int)
 418      */
 419     protected GridBagLayoutInfo layoutInfo;
 420 
 421     /**
 422      * This field holds the overrides to the column minimum
 423      * width.  If this field is non-<code>null</code> the values are
 424      * applied to the gridbag after all of the minimum columns
 425      * widths have been calculated.
 426      * If columnWidths has more elements than the number of
 427      * columns, columns are added to the gridbag to match
 428      * the number of elements in columnWidth.
 429      *
 430      * @serial
 431      * @see #getLayoutDimensions()
 432      */
 433     public int columnWidths[];
 434 
 435     /**
 436      * This field holds the overrides to the row minimum
 437      * heights.  If this field is non-<code>null</code> the values are
 438      * applied to the gridbag after all of the minimum row
 439      * heights have been calculated.
 440      * If <code>rowHeights</code> has more elements than the number of
 441      * rows, rowa are added to the gridbag to match
 442      * the number of elements in <code>rowHeights</code>.
 443      *
 444      * @serial
 445      * @see #getLayoutDimensions()
 446      */
 447     public int rowHeights[];
 448 
 449     /**
 450      * This field holds the overrides to the column weights.
 451      * If this field is non-<code>null</code> the values are
 452      * applied to the gridbag after all of the columns
 453      * weights have been calculated.
 454      * If <code>columnWeights[i]</code> &gt; weight for column i, then
 455      * column i is assigned the weight in <code>columnWeights[i]</code>.
 456      * If <code>columnWeights</code> has more elements than the number
 457      * of columns, the excess elements are ignored - they do
 458      * not cause more columns to be created.
 459      *
 460      * @serial
 461      */
 462     public double columnWeights[];
 463 
 464     /**
 465      * This field holds the overrides to the row weights.
 466      * If this field is non-<code>null</code> the values are
 467      * applied to the gridbag after all of the rows
 468      * weights have been calculated.
 469      * If <code>rowWeights[i]</code> &gt; weight for row i, then
 470      * row i is assigned the weight in <code>rowWeights[i]</code>.
 471      * If <code>rowWeights</code> has more elements than the number
 472      * of rows, the excess elements are ignored - they do
 473      * not cause more rows to be created.
 474      *
 475      * @serial
 476      */
 477     public double rowWeights[];
 478 
 479     /**
 480      * The component being positioned.  This is set before calling into
 481      * <code>adjustForGravity</code>.
 482      */
 483     private Component componentAdjusting;
 484 
 485     /**
 486      * Creates a grid bag layout manager.
 487      */
 488     public GridBagLayout () {
 489         comptable = new Hashtable<Component,GridBagConstraints>();
 490         defaultConstraints = new GridBagConstraints();
 491     }
 492 
 493     /**
 494      * Sets the constraints for the specified component in this layout.
 495      * @param       comp the component to be modified
 496      * @param       constraints the constraints to be applied
 497      */
 498     public void setConstraints(Component comp, GridBagConstraints constraints) {
 499         comptable.put(comp, (GridBagConstraints)constraints.clone());
 500     }
 501 
 502     /**
 503      * Gets the constraints for the specified component.  A copy of
 504      * the actual <code>GridBagConstraints</code> object is returned.
 505      * @param       comp the component to be queried
 506      * @return      the constraint for the specified component in this
 507      *                  grid bag layout; a copy of the actual constraint
 508      *                  object is returned
 509      */
 510     public GridBagConstraints getConstraints(Component comp) {
 511         GridBagConstraints constraints = comptable.get(comp);
 512         if (constraints == null) {
 513             setConstraints(comp, defaultConstraints);
 514             constraints = comptable.get(comp);
 515         }
 516         return (GridBagConstraints)constraints.clone();
 517     }
 518 
 519     /**
 520      * Retrieves the constraints for the specified component.
 521      * The return value is not a copy, but is the actual
 522      * <code>GridBagConstraints</code> object used by the layout mechanism.
 523      * <p>
 524      * If <code>comp</code> is not in the <code>GridBagLayout</code>,
 525      * a set of default <code>GridBagConstraints</code> are returned.
 526      * A <code>comp</code> value of <code>null</code> is invalid
 527      * and returns <code>null</code>.
 528      *
 529      * @param       comp the component to be queried
 530      * @return      the contraints for the specified component
 531      */
 532     protected GridBagConstraints lookupConstraints(Component comp) {
 533         GridBagConstraints constraints = comptable.get(comp);
 534         if (constraints == null) {
 535             setConstraints(comp, defaultConstraints);
 536             constraints = comptable.get(comp);
 537         }
 538         return constraints;
 539     }
 540 
 541     /**
 542      * Removes the constraints for the specified component in this layout
 543      * @param       comp the component to be modified
 544      */
 545     private void removeConstraints(Component comp) {
 546         comptable.remove(comp);
 547     }
 548 
 549     /**
 550      * Determines the origin of the layout area, in the graphics coordinate
 551      * space of the target container.  This value represents the pixel
 552      * coordinates of the top-left corner of the layout area regardless of
 553      * the <code>ComponentOrientation</code> value of the container.  This
 554      * is distinct from the grid origin given by the cell coordinates (0,0).
 555      * Most applications do not call this method directly.
 556      * @return     the graphics origin of the cell in the top-left
 557      *             corner of the layout grid
 558      * @see        java.awt.ComponentOrientation
 559      * @since      JDK1.1
 560      */
 561     public Point getLayoutOrigin () {
 562         Point origin = new Point(0,0);
 563         if (layoutInfo != null) {
 564             origin.x = layoutInfo.startx;
 565             origin.y = layoutInfo.starty;
 566         }
 567         return origin;
 568     }
 569 
 570     /**
 571      * Determines column widths and row heights for the layout grid.
 572      * <p>
 573      * Most applications do not call this method directly.
 574      * @return     an array of two arrays, containing the widths
 575      *                       of the layout columns and
 576      *                       the heights of the layout rows
 577      * @since      JDK1.1
 578      */
 579     public int [][] getLayoutDimensions () {
 580         if (layoutInfo == null)
 581             return new int[2][0];
 582 
 583         int dim[][] = new int [2][];
 584         dim[0] = new int[layoutInfo.width];
 585         dim[1] = new int[layoutInfo.height];
 586 
 587         System.arraycopy(layoutInfo.minWidth, 0, dim[0], 0, layoutInfo.width);
 588         System.arraycopy(layoutInfo.minHeight, 0, dim[1], 0, layoutInfo.height);
 589 
 590         return dim;
 591     }
 592 
 593     /**
 594      * Determines the weights of the layout grid's columns and rows.
 595      * Weights are used to calculate how much a given column or row
 596      * stretches beyond its preferred size, if the layout has extra
 597      * room to fill.
 598      * <p>
 599      * Most applications do not call this method directly.
 600      * @return      an array of two arrays, representing the
 601      *                    horizontal weights of the layout columns
 602      *                    and the vertical weights of the layout rows
 603      * @since       JDK1.1
 604      */
 605     public double [][] getLayoutWeights () {
 606         if (layoutInfo == null)
 607             return new double[2][0];
 608 
 609         double weights[][] = new double [2][];
 610         weights[0] = new double[layoutInfo.width];
 611         weights[1] = new double[layoutInfo.height];
 612 
 613         System.arraycopy(layoutInfo.weightX, 0, weights[0], 0, layoutInfo.width);
 614         System.arraycopy(layoutInfo.weightY, 0, weights[1], 0, layoutInfo.height);
 615 
 616         return weights;
 617     }
 618 
 619     /**
 620      * Determines which cell in the layout grid contains the point
 621      * specified by <code>(x,&nbsp;y)</code>. Each cell is identified
 622      * by its column index (ranging from 0 to the number of columns
 623      * minus 1) and its row index (ranging from 0 to the number of
 624      * rows minus 1).
 625      * <p>
 626      * If the <code>(x,&nbsp;y)</code> point lies
 627      * outside the grid, the following rules are used.
 628      * The column index is returned as zero if <code>x</code> lies to the
 629      * left of the layout for a left-to-right container or to the right of
 630      * the layout for a right-to-left container.  The column index is returned
 631      * as the number of columns if <code>x</code> lies
 632      * to the right of the layout in a left-to-right container or to the left
 633      * in a right-to-left container.
 634      * The row index is returned as zero if <code>y</code> lies above the
 635      * layout, and as the number of rows if <code>y</code> lies
 636      * below the layout.  The orientation of a container is determined by its
 637      * <code>ComponentOrientation</code> property.
 638      * @param      x    the <i>x</i> coordinate of a point
 639      * @param      y    the <i>y</i> coordinate of a point
 640      * @return     an ordered pair of indexes that indicate which cell
 641      *             in the layout grid contains the point
 642      *             (<i>x</i>,&nbsp;<i>y</i>).
 643      * @see        java.awt.ComponentOrientation
 644      * @since      JDK1.1
 645      */
 646     public Point location(int x, int y) {
 647         Point loc = new Point(0,0);
 648         int i, d;
 649 
 650         if (layoutInfo == null)
 651             return loc;
 652 
 653         d = layoutInfo.startx;
 654         if (!rightToLeft) {
 655             for (i=0; i<layoutInfo.width; i++) {
 656                 d += layoutInfo.minWidth[i];
 657                 if (d > x)
 658                     break;
 659             }
 660         } else {
 661             for (i=layoutInfo.width-1; i>=0; i--) {
 662                 if (d > x)
 663                     break;
 664                 d += layoutInfo.minWidth[i];
 665             }
 666             i++;
 667         }
 668         loc.x = i;
 669 
 670         d = layoutInfo.starty;
 671         for (i=0; i<layoutInfo.height; i++) {
 672             d += layoutInfo.minHeight[i];
 673             if (d > y)
 674                 break;
 675         }
 676         loc.y = i;
 677 
 678         return loc;
 679     }
 680 
 681     /**
 682      * Has no effect, since this layout manager does not use a per-component string.
 683      */
 684     public void addLayoutComponent(String name, Component comp) {
 685     }
 686 
 687     /**
 688      * Adds the specified component to the layout, using the specified
 689      * <code>constraints</code> object.  Note that constraints
 690      * are mutable and are, therefore, cloned when cached.
 691      *
 692      * @param      comp         the component to be added
 693      * @param      constraints  an object that determines how
 694      *                          the component is added to the layout
 695      * @exception IllegalArgumentException if <code>constraints</code>
 696      *            is not a <code>GridBagConstraint</code>
 697      */
 698     public void addLayoutComponent(Component comp, Object constraints) {
 699         if (constraints instanceof GridBagConstraints) {
 700             setConstraints(comp, (GridBagConstraints)constraints);
 701         } else if (constraints != null) {
 702             throw new IllegalArgumentException("cannot add to layout: constraints must be a GridBagConstraint");
 703         }
 704     }
 705 
 706     /**
 707      * Removes the specified component from this layout.
 708      * <p>
 709      * Most applications do not call this method directly.
 710      * @param    comp   the component to be removed.
 711      * @see      java.awt.Container#remove(java.awt.Component)
 712      * @see      java.awt.Container#removeAll()
 713      */
 714     public void removeLayoutComponent(Component comp) {
 715         removeConstraints(comp);
 716     }
 717 
 718     /**
 719      * Determines the preferred size of the <code>parent</code>
 720      * container using this grid bag layout.
 721      * <p>
 722      * Most applications do not call this method directly.
 723      *
 724      * @param     parent   the container in which to do the layout
 725      * @see       java.awt.Container#getPreferredSize
 726      * @return the preferred size of the <code>parent</code>
 727      *  container
 728      */
 729     public Dimension preferredLayoutSize(Container parent) {
 730         GridBagLayoutInfo info = getLayoutInfo(parent, PREFERREDSIZE);
 731         return getMinSize(parent, info);
 732     }
 733 
 734     /**
 735      * Determines the minimum size of the <code>parent</code> container
 736      * using this grid bag layout.
 737      * <p>
 738      * Most applications do not call this method directly.
 739      * @param     parent   the container in which to do the layout
 740      * @see       java.awt.Container#doLayout
 741      * @return the minimum size of the <code>parent</code> container
 742      */
 743     public Dimension minimumLayoutSize(Container parent) {
 744         GridBagLayoutInfo info = getLayoutInfo(parent, MINSIZE);
 745         return getMinSize(parent, info);
 746     }
 747 
 748     /**
 749      * Returns the maximum dimensions for this layout given the components
 750      * in the specified target container.
 751      * @param target the container which needs to be laid out
 752      * @see Container
 753      * @see #minimumLayoutSize(Container)
 754      * @see #preferredLayoutSize(Container)
 755      * @return the maximum dimensions for this layout
 756      */
 757     public Dimension maximumLayoutSize(Container target) {
 758         return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
 759     }
 760 
 761     /**
 762      * Returns the alignment along the x axis.  This specifies how
 763      * the component would like to be aligned relative to other
 764      * components.  The value should be a number between 0 and 1
 765      * where 0 represents alignment along the origin, 1 is aligned
 766      * the furthest away from the origin, 0.5 is centered, etc.
 767      * <p>
 768      * @return the value <code>0.5f</code> to indicate centered
 769      */
 770     public float getLayoutAlignmentX(Container parent) {
 771         return 0.5f;
 772     }
 773 
 774     /**
 775      * Returns the alignment along the y axis.  This specifies how
 776      * the component would like to be aligned relative to other
 777      * components.  The value should be a number between 0 and 1
 778      * where 0 represents alignment along the origin, 1 is aligned
 779      * the furthest away from the origin, 0.5 is centered, etc.
 780      * <p>
 781      * @return the value <code>0.5f</code> to indicate centered
 782      */
 783     public float getLayoutAlignmentY(Container parent) {
 784         return 0.5f;
 785     }
 786 
 787     /**
 788      * Invalidates the layout, indicating that if the layout manager
 789      * has cached information it should be discarded.
 790      */
 791     public void invalidateLayout(Container target) {
 792     }
 793 
 794     /**
 795      * Lays out the specified container using this grid bag layout.
 796      * This method reshapes components in the specified container in
 797      * order to satisfy the contraints of this <code>GridBagLayout</code>
 798      * object.
 799      * <p>
 800      * Most applications do not call this method directly.
 801      * @param parent the container in which to do the layout
 802      * @see java.awt.Container
 803      * @see java.awt.Container#doLayout
 804      */
 805     public void layoutContainer(Container parent) {
 806         arrangeGrid(parent);
 807     }
 808 
 809     /**
 810      * Returns a string representation of this grid bag layout's values.
 811      * @return     a string representation of this grid bag layout.
 812      */
 813     public String toString() {
 814         return getClass().getName();
 815     }
 816 
 817     /**
 818      * Print the layout information.  Useful for debugging.
 819      */
 820 
 821     /* DEBUG
 822      *
 823      *  protected void dumpLayoutInfo(GridBagLayoutInfo s) {
 824      *    int x;
 825      *
 826      *    System.out.println("Col\tWidth\tWeight");
 827      *    for (x=0; x<s.width; x++) {
 828      *      System.out.println(x + "\t" +
 829      *                   s.minWidth[x] + "\t" +
 830      *                   s.weightX[x]);
 831      *    }
 832      *    System.out.println("Row\tHeight\tWeight");
 833      *    for (x=0; x<s.height; x++) {
 834      *      System.out.println(x + "\t" +
 835      *                   s.minHeight[x] + "\t" +
 836      *                   s.weightY[x]);
 837      *    }
 838      *  }
 839      */
 840 
 841     /**
 842      * Print the layout constraints.  Useful for debugging.
 843      */
 844 
 845     /* DEBUG
 846      *
 847      *  protected void dumpConstraints(GridBagConstraints constraints) {
 848      *    System.out.println(
 849      *                 "wt " +
 850      *                 constraints.weightx +
 851      *                 " " +
 852      *                 constraints.weighty +
 853      *                 ", " +
 854      *
 855      *                 "box " +
 856      *                 constraints.gridx +
 857      *                 " " +
 858      *                 constraints.gridy +
 859      *                 " " +
 860      *                 constraints.gridwidth +
 861      *                 " " +
 862      *                 constraints.gridheight +
 863      *                 ", " +
 864      *
 865      *                 "min " +
 866      *                 constraints.minWidth +
 867      *                 " " +
 868      *                 constraints.minHeight +
 869      *                 ", " +
 870      *
 871      *                 "pad " +
 872      *                 constraints.insets.bottom +
 873      *                 " " +
 874      *                 constraints.insets.left +
 875      *                 " " +
 876      *                 constraints.insets.right +
 877      *                 " " +
 878      *                 constraints.insets.top +
 879      *                 " " +
 880      *                 constraints.ipadx +
 881      *                 " " +
 882      *                 constraints.ipady);
 883      *  }
 884      */
 885 
 886     /**
 887      * Fills in an instance of <code>GridBagLayoutInfo</code> for the
 888      * current set of managed children. This requires three passes through the
 889      * set of children:
 890      *
 891      * <ol>
 892      * <li>Figure out the dimensions of the layout grid.
 893      * <li>Determine which cells the components occupy.
 894      * <li>Distribute the weights and min sizes amoung the rows/columns.
 895      * </ol>
 896      *
 897      * This also caches the minsizes for all the children when they are
 898      * first encountered (so subsequent loops don't need to ask again).
 899      * <p>
 900      * This method should only be used internally by
 901      * <code>GridBagLayout</code>.
 902      *
 903      * @param parent  the layout container
 904      * @param sizeflag either <code>PREFERREDSIZE</code> or
 905      *   <code>MINSIZE</code>
 906      * @return the <code>GridBagLayoutInfo</code> for the set of children
 907      * @since 1.4
 908      */
 909     protected GridBagLayoutInfo getLayoutInfo(Container parent, int sizeflag) {
 910         return GetLayoutInfo(parent, sizeflag);
 911     }
 912 
 913     /*
 914      * Calculate maximum array sizes to allocate arrays without ensureCapacity
 915      * we may use preCalculated sizes in whole class because of upper estimation of
 916      * maximumArrayXIndex and maximumArrayYIndex.
 917      */
 918 
 919     private long[]  preInitMaximumArraySizes(Container parent){
 920         Component components[] = parent.getComponents();
 921         Component comp;
 922         GridBagConstraints constraints;
 923         int curX, curY;
 924         int curWidth, curHeight;
 925         int preMaximumArrayXIndex = 0;
 926         int preMaximumArrayYIndex = 0;
 927         long [] returnArray = new long[2];
 928 
 929         for (int compId = 0 ; compId < components.length ; compId++) {
 930             comp = components[compId];
 931             if (!comp.isVisible()) {
 932                 continue;
 933             }
 934 
 935             constraints = lookupConstraints(comp);
 936             curX = constraints.gridx;
 937             curY = constraints.gridy;
 938             curWidth = constraints.gridwidth;
 939             curHeight = constraints.gridheight;
 940 
 941             // -1==RELATIVE, means that column|row equals to previously added component,
 942             // since each next Component with gridx|gridy == RELATIVE starts from
 943             // previous position, so we should start from previous component which
 944             // already used in maximumArray[X|Y]Index calculation. We could just increase
 945             // maximum by 1 to handle situation when component with gridx=-1 was added.
 946             if (curX < 0){
 947                 curX = ++preMaximumArrayYIndex;
 948             }
 949             if (curY < 0){
 950                 curY = ++preMaximumArrayXIndex;
 951             }
 952             // gridwidth|gridheight may be equal to RELATIVE (-1) or REMAINDER (0)
 953             // in any case using 1 instead of 0 or -1 should be sufficient to for
 954             // correct maximumArraySizes calculation
 955             if (curWidth <= 0){
 956                 curWidth = 1;
 957             }
 958             if (curHeight <= 0){
 959                 curHeight = 1;
 960             }
 961 
 962             preMaximumArrayXIndex = Math.max(curY + curHeight, preMaximumArrayXIndex);
 963             preMaximumArrayYIndex = Math.max(curX + curWidth, preMaximumArrayYIndex);
 964         } //for (components) loop
 965         // Must specify index++ to allocate well-working arrays.
 966         /* fix for 4623196.
 967          * now return long array instead of Point
 968          */
 969         returnArray[0] = preMaximumArrayXIndex;
 970         returnArray[1] = preMaximumArrayYIndex;
 971         return returnArray;
 972     } //PreInitMaximumSizes
 973 
 974     /**
 975      * This method is obsolete and supplied for backwards
 976      * compatability only; new code should call {@link
 977      * #getLayoutInfo(java.awt.Container, int) getLayoutInfo} instead.
 978      * This method is the same as <code>getLayoutInfo</code>;
 979      * refer to <code>getLayoutInfo</code> for details on parameters
 980      * and return value.
 981      */
 982     protected GridBagLayoutInfo GetLayoutInfo(Container parent, int sizeflag) {
 983         synchronized (parent.getTreeLock()) {
 984             GridBagLayoutInfo r;
 985             Component comp;
 986             GridBagConstraints constraints;
 987             Dimension d;
 988             Component components[] = parent.getComponents();
 989             // Code below will address index curX+curWidth in the case of yMaxArray, weightY
 990             // ( respectively curY+curHeight for xMaxArray, weightX ) where
 991             //  curX in 0 to preInitMaximumArraySizes.y
 992             // Thus, the maximum index that could
 993             // be calculated in the following code is curX+curX.
 994             // EmpericMultier equals 2 because of this.
 995 
 996             int layoutWidth, layoutHeight;
 997             int []xMaxArray;
 998             int []yMaxArray;
 999             int compindex, i, k, px, py, pixels_diff, nextSize;
1000             int curX = 0; // constraints.gridx
1001             int curY = 0; // constraints.gridy
1002             int curWidth = 1;  // constraints.gridwidth
1003             int curHeight = 1;  // constraints.gridheight
1004             int curRow, curCol;
1005             double weight_diff, weight;
1006             int maximumArrayXIndex = 0;
1007             int maximumArrayYIndex = 0;
1008             int anchor;
1009 
1010             /*
1011              * Pass #1
1012              *
1013              * Figure out the dimensions of the layout grid (use a value of 1 for
1014              * zero or negative widths and heights).
1015              */
1016 
1017             layoutWidth = layoutHeight = 0;
1018             curRow = curCol = -1;
1019             long [] arraySizes = preInitMaximumArraySizes(parent);
1020 
1021             /* fix for 4623196.
1022              * If user try to create a very big grid we can
1023              * get NegativeArraySizeException because of integer value
1024              * overflow (EMPIRICMULTIPLIER*gridSize might be more then Integer.MAX_VALUE).
1025              * We need to detect this situation and try to create a
1026              * grid with Integer.MAX_VALUE size instead.
1027              */
1028             maximumArrayXIndex = (EMPIRICMULTIPLIER * arraySizes[0] > Integer.MAX_VALUE )? Integer.MAX_VALUE : EMPIRICMULTIPLIER*(int)arraySizes[0];
1029             maximumArrayYIndex = (EMPIRICMULTIPLIER * arraySizes[1] > Integer.MAX_VALUE )? Integer.MAX_VALUE : EMPIRICMULTIPLIER*(int)arraySizes[1];
1030 
1031             if (rowHeights != null){
1032                 maximumArrayXIndex = Math.max(maximumArrayXIndex, rowHeights.length);
1033             }
1034             if (columnWidths != null){
1035                 maximumArrayYIndex = Math.max(maximumArrayYIndex, columnWidths.length);
1036             }
1037 
1038             xMaxArray = new int[maximumArrayXIndex];
1039             yMaxArray = new int[maximumArrayYIndex];
1040 
1041             boolean hasBaseline = false;
1042             for (compindex = 0 ; compindex < components.length ; compindex++) {
1043                 comp = components[compindex];
1044                 if (!comp.isVisible())
1045                     continue;
1046                 constraints = lookupConstraints(comp);
1047 
1048                 curX = constraints.gridx;
1049                 curY = constraints.gridy;
1050                 curWidth = constraints.gridwidth;
1051                 if (curWidth <= 0)
1052                     curWidth = 1;
1053                 curHeight = constraints.gridheight;
1054                 if (curHeight <= 0)
1055                     curHeight = 1;
1056 
1057                 /* If x or y is negative, then use relative positioning: */
1058                 if (curX < 0 && curY < 0) {
1059                     if (curRow >= 0)
1060                         curY = curRow;
1061                     else if (curCol >= 0)
1062                         curX = curCol;
1063                     else
1064                         curY = 0;
1065                 }
1066                 if (curX < 0) {
1067                     px = 0;
1068                     for (i = curY; i < (curY + curHeight); i++) {
1069                         px = Math.max(px, xMaxArray[i]);
1070                     }
1071 
1072                     curX = px - curX - 1;
1073                     if(curX < 0)
1074                         curX = 0;
1075                 }
1076                 else if (curY < 0) {
1077                     py = 0;
1078                     for (i = curX; i < (curX + curWidth); i++) {
1079                         py = Math.max(py, yMaxArray[i]);
1080                     }
1081                     curY = py - curY - 1;
1082                     if(curY < 0)
1083                         curY = 0;
1084                 }
1085 
1086                 /* Adjust the grid width and height
1087                  *  fix for 5005945: unneccessary loops removed
1088                  */
1089                 px = curX + curWidth;
1090                 if (layoutWidth < px) {
1091                     layoutWidth = px;
1092                 }
1093                 py = curY + curHeight;
1094                 if (layoutHeight < py) {
1095                     layoutHeight = py;
1096                 }
1097 
1098                 /* Adjust xMaxArray and yMaxArray */
1099                 for (i = curX; i < (curX + curWidth); i++) {
1100                     yMaxArray[i] =py;
1101                 }
1102                 for (i = curY; i < (curY + curHeight); i++) {
1103                     xMaxArray[i] = px;
1104                 }
1105 
1106 
1107                 /* Cache the current slave's size. */
1108                 if (sizeflag == PREFERREDSIZE)
1109                     d = comp.getPreferredSize();
1110                 else
1111                     d = comp.getMinimumSize();
1112                 constraints.minWidth = d.width;
1113                 constraints.minHeight = d.height;
1114                 if (calculateBaseline(comp, constraints, d)) {
1115                     hasBaseline = true;
1116                 }
1117 
1118                 /* Zero width and height must mean that this is the last item (or
1119                  * else something is wrong). */
1120                 if (constraints.gridheight == 0 && constraints.gridwidth == 0)
1121                     curRow = curCol = -1;
1122 
1123                 /* Zero width starts a new row */
1124                 if (constraints.gridheight == 0 && curRow < 0)
1125                     curCol = curX + curWidth;
1126 
1127                 /* Zero height starts a new column */
1128                 else if (constraints.gridwidth == 0 && curCol < 0)
1129                     curRow = curY + curHeight;
1130             } //for (components) loop
1131 
1132 
1133             /*
1134              * Apply minimum row/column dimensions
1135              */
1136             if (columnWidths != null && layoutWidth < columnWidths.length)
1137                 layoutWidth = columnWidths.length;
1138             if (rowHeights != null && layoutHeight < rowHeights.length)
1139                 layoutHeight = rowHeights.length;
1140 
1141             r = new GridBagLayoutInfo(layoutWidth, layoutHeight);
1142 
1143             /*
1144              * Pass #2
1145              *
1146              * Negative values for gridX are filled in with the current x value.
1147              * Negative values for gridY are filled in with the current y value.
1148              * Negative or zero values for gridWidth and gridHeight end the current
1149              *  row or column, respectively.
1150              */
1151 
1152             curRow = curCol = -1;
1153 
1154             Arrays.fill(xMaxArray, 0);
1155             Arrays.fill(yMaxArray, 0);
1156 
1157             int[] maxAscent = null;
1158             int[] maxDescent = null;
1159             short[] baselineType = null;
1160 
1161             if (hasBaseline) {
1162                 r.maxAscent = maxAscent = new int[layoutHeight];
1163                 r.maxDescent = maxDescent = new int[layoutHeight];
1164                 r.baselineType = baselineType = new short[layoutHeight];
1165                 r.hasBaseline = true;
1166             }
1167 
1168 
1169             for (compindex = 0 ; compindex < components.length ; compindex++) {
1170                 comp = components[compindex];
1171                 if (!comp.isVisible())
1172                     continue;
1173                 constraints = lookupConstraints(comp);
1174 
1175                 curX = constraints.gridx;
1176                 curY = constraints.gridy;
1177                 curWidth = constraints.gridwidth;
1178                 curHeight = constraints.gridheight;
1179 
1180                 /* If x or y is negative, then use relative positioning: */
1181                 if (curX < 0 && curY < 0) {
1182                     if(curRow >= 0)
1183                         curY = curRow;
1184                     else if(curCol >= 0)
1185                         curX = curCol;
1186                     else
1187                         curY = 0;
1188                 }
1189 
1190                 if (curX < 0) {
1191                     if (curHeight <= 0) {
1192                         curHeight += r.height - curY;
1193                         if (curHeight < 1)
1194                             curHeight = 1;
1195                     }
1196 
1197                     px = 0;
1198                     for (i = curY; i < (curY + curHeight); i++)
1199                         px = Math.max(px, xMaxArray[i]);
1200 
1201                     curX = px - curX - 1;
1202                     if(curX < 0)
1203                         curX = 0;
1204                 }
1205                 else if (curY < 0) {
1206                     if (curWidth <= 0) {
1207                         curWidth += r.width - curX;
1208                         if (curWidth < 1)
1209                             curWidth = 1;
1210                     }
1211 
1212                     py = 0;
1213                     for (i = curX; i < (curX + curWidth); i++){
1214                         py = Math.max(py, yMaxArray[i]);
1215                     }
1216 
1217                     curY = py - curY - 1;
1218                     if(curY < 0)
1219                         curY = 0;
1220                 }
1221 
1222                 if (curWidth <= 0) {
1223                     curWidth += r.width - curX;
1224                     if (curWidth < 1)
1225                         curWidth = 1;
1226                 }
1227 
1228                 if (curHeight <= 0) {
1229                     curHeight += r.height - curY;
1230                     if (curHeight < 1)
1231                         curHeight = 1;
1232                 }
1233 
1234                 px = curX + curWidth;
1235                 py = curY + curHeight;
1236 
1237                 for (i = curX; i < (curX + curWidth); i++) { yMaxArray[i] = py; }
1238                 for (i = curY; i < (curY + curHeight); i++) { xMaxArray[i] = px; }
1239 
1240                 /* Make negative sizes start a new row/column */
1241                 if (constraints.gridheight == 0 && constraints.gridwidth == 0)
1242                     curRow = curCol = -1;
1243                 if (constraints.gridheight == 0 && curRow < 0)
1244                     curCol = curX + curWidth;
1245                 else if (constraints.gridwidth == 0 && curCol < 0)
1246                     curRow = curY + curHeight;
1247 
1248                 /* Assign the new values to the gridbag slave */
1249                 constraints.tempX = curX;
1250                 constraints.tempY = curY;
1251                 constraints.tempWidth = curWidth;
1252                 constraints.tempHeight = curHeight;
1253 
1254                 anchor = constraints.anchor;
1255                 if (hasBaseline) {
1256                     switch(anchor) {
1257                     case GridBagConstraints.BASELINE:
1258                     case GridBagConstraints.BASELINE_LEADING:
1259                     case GridBagConstraints.BASELINE_TRAILING:
1260                         if (constraints.ascent >= 0) {
1261                             if (curHeight == 1) {
1262                                 maxAscent[curY] =
1263                                         Math.max(maxAscent[curY],
1264                                                  constraints.ascent);
1265                                 maxDescent[curY] =
1266                                         Math.max(maxDescent[curY],
1267                                                  constraints.descent);
1268                             }
1269                             else {
1270                                 if (constraints.baselineResizeBehavior ==
1271                                         Component.BaselineResizeBehavior.
1272                                         CONSTANT_DESCENT) {
1273                                     maxDescent[curY + curHeight - 1] =
1274                                         Math.max(maxDescent[curY + curHeight
1275                                                             - 1],
1276                                                  constraints.descent);
1277                                 }
1278                                 else {
1279                                     maxAscent[curY] = Math.max(maxAscent[curY],
1280                                                            constraints.ascent);
1281                                 }
1282                             }
1283                             if (constraints.baselineResizeBehavior ==
1284                                     Component.BaselineResizeBehavior.CONSTANT_DESCENT) {
1285                                 baselineType[curY + curHeight - 1] |=
1286                                         (1 << constraints.
1287                                          baselineResizeBehavior.ordinal());
1288                             }
1289                             else {
1290                                 baselineType[curY] |= (1 << constraints.
1291                                              baselineResizeBehavior.ordinal());
1292                             }
1293                         }
1294                         break;
1295                     case GridBagConstraints.ABOVE_BASELINE:
1296                     case GridBagConstraints.ABOVE_BASELINE_LEADING:
1297                     case GridBagConstraints.ABOVE_BASELINE_TRAILING:
1298                         // Component positioned above the baseline.
1299                         // To make the bottom edge of the component aligned
1300                         // with the baseline the bottom inset is
1301                         // added to the descent, the rest to the ascent.
1302                         pixels_diff = constraints.minHeight +
1303                                 constraints.insets.top +
1304                                 constraints.ipady;
1305                         maxAscent[curY] = Math.max(maxAscent[curY],
1306                                                    pixels_diff);
1307                         maxDescent[curY] = Math.max(maxDescent[curY],
1308                                                     constraints.insets.bottom);
1309                         break;
1310                     case GridBagConstraints.BELOW_BASELINE:
1311                     case GridBagConstraints.BELOW_BASELINE_LEADING:
1312                     case GridBagConstraints.BELOW_BASELINE_TRAILING:
1313                         // Component positioned below the baseline.
1314                         // To make the top edge of the component aligned
1315                         // with the baseline the top inset is
1316                         // added to the ascent, the rest to the descent.
1317                         pixels_diff = constraints.minHeight +
1318                                 constraints.insets.bottom + constraints.ipady;
1319                         maxDescent[curY] = Math.max(maxDescent[curY],
1320                                                     pixels_diff);
1321                         maxAscent[curY] = Math.max(maxAscent[curY],
1322                                                    constraints.insets.top);
1323                         break;
1324                     }
1325                 }
1326             }
1327 
1328             r.weightX = new double[maximumArrayYIndex];
1329             r.weightY = new double[maximumArrayXIndex];
1330             r.minWidth = new int[maximumArrayYIndex];
1331             r.minHeight = new int[maximumArrayXIndex];
1332 
1333 
1334             /*
1335              * Apply minimum row/column dimensions and weights
1336              */
1337             if (columnWidths != null)
1338                 System.arraycopy(columnWidths, 0, r.minWidth, 0, columnWidths.length);
1339             if (rowHeights != null)
1340                 System.arraycopy(rowHeights, 0, r.minHeight, 0, rowHeights.length);
1341             if (columnWeights != null)
1342                 System.arraycopy(columnWeights, 0, r.weightX, 0,  Math.min(r.weightX.length, columnWeights.length));
1343             if (rowWeights != null)
1344                 System.arraycopy(rowWeights, 0, r.weightY, 0,  Math.min(r.weightY.length, rowWeights.length));
1345 
1346             /*
1347              * Pass #3
1348              *
1349              * Distribute the minimun widths and weights:
1350              */
1351 
1352             nextSize = Integer.MAX_VALUE;
1353 
1354             for (i = 1;
1355                  i != Integer.MAX_VALUE;
1356                  i = nextSize, nextSize = Integer.MAX_VALUE) {
1357                 for (compindex = 0 ; compindex < components.length ; compindex++) {
1358                     comp = components[compindex];
1359                     if (!comp.isVisible())
1360                         continue;
1361                     constraints = lookupConstraints(comp);
1362 
1363                     if (constraints.tempWidth == i) {
1364                         px = constraints.tempX + constraints.tempWidth; /* right column */
1365 
1366                         /*
1367                          * Figure out if we should use this slave\'s weight.  If the weight
1368                          * is less than the total weight spanned by the width of the cell,
1369                          * then discard the weight.  Otherwise split the difference
1370                          * according to the existing weights.
1371                          */
1372 
1373                         weight_diff = constraints.weightx;
1374                         for (k = constraints.tempX; k < px; k++)
1375                             weight_diff -= r.weightX[k];
1376                         if (weight_diff > 0.0) {
1377                             weight = 0.0;
1378                             for (k = constraints.tempX; k < px; k++)
1379                                 weight += r.weightX[k];
1380                             for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
1381                                 double wt = r.weightX[k];
1382                                 double dx = (wt * weight_diff) / weight;
1383                                 r.weightX[k] += dx;
1384                                 weight_diff -= dx;
1385                                 weight -= wt;
1386                             }
1387                             /* Assign the remainder to the rightmost cell */
1388                             r.weightX[px-1] += weight_diff;
1389                         }
1390 
1391                         /*
1392                          * Calculate the minWidth array values.
1393                          * First, figure out how wide the current slave needs to be.
1394                          * Then, see if it will fit within the current minWidth values.
1395                          * If it will not fit, add the difference according to the
1396                          * weightX array.
1397                          */
1398 
1399                         pixels_diff =
1400                             constraints.minWidth + constraints.ipadx +
1401                             constraints.insets.left + constraints.insets.right;
1402 
1403                         for (k = constraints.tempX; k < px; k++)
1404                             pixels_diff -= r.minWidth[k];
1405                         if (pixels_diff > 0) {
1406                             weight = 0.0;
1407                             for (k = constraints.tempX; k < px; k++)
1408                                 weight += r.weightX[k];
1409                             for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
1410                                 double wt = r.weightX[k];
1411                                 int dx = (int)((wt * ((double)pixels_diff)) / weight);
1412                                 r.minWidth[k] += dx;
1413                                 pixels_diff -= dx;
1414                                 weight -= wt;
1415                             }
1416                             /* Any leftovers go into the rightmost cell */
1417                             r.minWidth[px-1] += pixels_diff;
1418                         }
1419                     }
1420                     else if (constraints.tempWidth > i && constraints.tempWidth < nextSize)
1421                         nextSize = constraints.tempWidth;
1422 
1423 
1424                     if (constraints.tempHeight == i) {
1425                         py = constraints.tempY + constraints.tempHeight; /* bottom row */
1426 
1427                         /*
1428                          * Figure out if we should use this slave's weight.  If the weight
1429                          * is less than the total weight spanned by the height of the cell,
1430                          * then discard the weight.  Otherwise split it the difference
1431                          * according to the existing weights.
1432                          */
1433 
1434                         weight_diff = constraints.weighty;
1435                         for (k = constraints.tempY; k < py; k++)
1436                             weight_diff -= r.weightY[k];
1437                         if (weight_diff > 0.0) {
1438                             weight = 0.0;
1439                             for (k = constraints.tempY; k < py; k++)
1440                                 weight += r.weightY[k];
1441                             for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
1442                                 double wt = r.weightY[k];
1443                                 double dy = (wt * weight_diff) / weight;
1444                                 r.weightY[k] += dy;
1445                                 weight_diff -= dy;
1446                                 weight -= wt;
1447                             }
1448                             /* Assign the remainder to the bottom cell */
1449                             r.weightY[py-1] += weight_diff;
1450                         }
1451 
1452                         /*
1453                          * Calculate the minHeight array values.
1454                          * First, figure out how tall the current slave needs to be.
1455                          * Then, see if it will fit within the current minHeight values.
1456                          * If it will not fit, add the difference according to the
1457                          * weightY array.
1458                          */
1459 
1460                         pixels_diff = -1;
1461                         if (hasBaseline) {
1462                             switch(constraints.anchor) {
1463                             case GridBagConstraints.BASELINE:
1464                             case GridBagConstraints.BASELINE_LEADING:
1465                             case GridBagConstraints.BASELINE_TRAILING:
1466                                 if (constraints.ascent >= 0) {
1467                                     if (constraints.tempHeight == 1) {
1468                                         pixels_diff =
1469                                             maxAscent[constraints.tempY] +
1470                                             maxDescent[constraints.tempY];
1471                                     }
1472                                     else if (constraints.baselineResizeBehavior !=
1473                                              Component.BaselineResizeBehavior.
1474                                              CONSTANT_DESCENT) {
1475                                         pixels_diff =
1476                                                 maxAscent[constraints.tempY] +
1477                                                 constraints.descent;
1478                                     }
1479                                     else {
1480                                         pixels_diff = constraints.ascent +
1481                                                 maxDescent[constraints.tempY +
1482                                                    constraints.tempHeight - 1];
1483                                     }
1484                                 }
1485                                 break;
1486                             case GridBagConstraints.ABOVE_BASELINE:
1487                             case GridBagConstraints.ABOVE_BASELINE_LEADING:
1488                             case GridBagConstraints.ABOVE_BASELINE_TRAILING:
1489                                 pixels_diff = constraints.insets.top +
1490                                         constraints.minHeight +
1491                                         constraints.ipady +
1492                                         maxDescent[constraints.tempY];
1493                                 break;
1494                             case GridBagConstraints.BELOW_BASELINE:
1495                             case GridBagConstraints.BELOW_BASELINE_LEADING:
1496                             case GridBagConstraints.BELOW_BASELINE_TRAILING:
1497                                 pixels_diff = maxAscent[constraints.tempY] +
1498                                         constraints.minHeight +
1499                                         constraints.insets.bottom +
1500                                         constraints.ipady;
1501                                 break;
1502                             }
1503                         }
1504                         if (pixels_diff == -1) {
1505                             pixels_diff =
1506                                 constraints.minHeight + constraints.ipady +
1507                                 constraints.insets.top +
1508                                 constraints.insets.bottom;
1509                         }
1510                         for (k = constraints.tempY; k < py; k++)
1511                             pixels_diff -= r.minHeight[k];
1512                         if (pixels_diff > 0) {
1513                             weight = 0.0;
1514                             for (k = constraints.tempY; k < py; k++)
1515                                 weight += r.weightY[k];
1516                             for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
1517                                 double wt = r.weightY[k];
1518                                 int dy = (int)((wt * ((double)pixels_diff)) / weight);
1519                                 r.minHeight[k] += dy;
1520                                 pixels_diff -= dy;
1521                                 weight -= wt;
1522                             }
1523                             /* Any leftovers go into the bottom cell */
1524                             r.minHeight[py-1] += pixels_diff;
1525                         }
1526                     }
1527                     else if (constraints.tempHeight > i &&
1528                              constraints.tempHeight < nextSize)
1529                         nextSize = constraints.tempHeight;
1530                 }
1531             }
1532             return r;
1533         }
1534     } //getLayoutInfo()
1535 
1536     /**
1537      * Calculate the baseline for the specified component.
1538      * If {@code c} is positioned along it's baseline, the baseline is
1539      * obtained and the {@code constraints} ascent, descent and
1540      * baseline resize behavior are set from the component; and true is
1541      * returned. Otherwise false is returned.
1542      */
1543     private boolean calculateBaseline(Component c,
1544                                       GridBagConstraints constraints,
1545                                       Dimension size) {
1546         int anchor = constraints.anchor;
1547         if (anchor == GridBagConstraints.BASELINE ||
1548                 anchor == GridBagConstraints.BASELINE_LEADING ||
1549                 anchor == GridBagConstraints.BASELINE_TRAILING) {
1550             // Apply the padding to the component, then ask for the baseline.
1551             int w = size.width + constraints.ipadx;
1552             int h = size.height + constraints.ipady;
1553             constraints.ascent = c.getBaseline(w, h);
1554             if (constraints.ascent >= 0) {
1555                 // Component has a baseline
1556                 int baseline = constraints.ascent;
1557                 // Adjust the ascent and descent to include the insets.
1558                 constraints.descent = h - constraints.ascent +
1559                             constraints.insets.bottom;
1560                 constraints.ascent += constraints.insets.top;
1561                 constraints.baselineResizeBehavior =
1562                         c.getBaselineResizeBehavior();
1563                 constraints.centerPadding = 0;
1564                 if (constraints.baselineResizeBehavior == Component.
1565                         BaselineResizeBehavior.CENTER_OFFSET) {
1566                     // Component has a baseline resize behavior of
1567                     // CENTER_OFFSET, calculate centerPadding and
1568                     // centerOffset (see the description of
1569                     // CENTER_OFFSET in the enum for detais on this
1570                     // algorithm).
1571                     int nextBaseline = c.getBaseline(w, h + 1);
1572                     constraints.centerOffset = baseline - h / 2;
1573                     if (h % 2 == 0) {
1574                         if (baseline != nextBaseline) {
1575                             constraints.centerPadding = 1;
1576                         }
1577                     }
1578                     else if (baseline == nextBaseline){
1579                         constraints.centerOffset--;
1580                         constraints.centerPadding = 1;
1581                     }
1582                 }
1583             }
1584             return true;
1585         }
1586         else {
1587             constraints.ascent = -1;
1588             return false;
1589         }
1590     }
1591 
1592     /**
1593      * Adjusts the x, y, width, and height fields to the correct
1594      * values depending on the constraint geometry and pads.
1595      * This method should only be used internally by
1596      * <code>GridBagLayout</code>.
1597      *
1598      * @param constraints the constraints to be applied
1599      * @param r the <code>Rectangle</code> to be adjusted
1600      * @since 1.4
1601      */
1602     protected void adjustForGravity(GridBagConstraints constraints,
1603                                     Rectangle r) {
1604         AdjustForGravity(constraints, r);
1605     }
1606 
1607     /**
1608      * This method is obsolete and supplied for backwards
1609      * compatability only; new code should call {@link
1610      * #adjustForGravity(java.awt.GridBagConstraints, java.awt.Rectangle)
1611      * adjustForGravity} instead.
1612      * This method is the same as <code>adjustForGravity</code>;
1613      * refer to <code>adjustForGravity</code> for details
1614      * on parameters.
1615      */
1616     protected void AdjustForGravity(GridBagConstraints constraints,
1617                                     Rectangle r) {
1618         int diffx, diffy;
1619         int cellY = r.y;
1620         int cellHeight = r.height;
1621 
1622         if (!rightToLeft) {
1623             r.x += constraints.insets.left;
1624         } else {
1625             r.x -= r.width - constraints.insets.right;
1626         }
1627         r.width -= (constraints.insets.left + constraints.insets.right);
1628         r.y += constraints.insets.top;
1629         r.height -= (constraints.insets.top + constraints.insets.bottom);
1630 
1631         diffx = 0;
1632         if ((constraints.fill != GridBagConstraints.HORIZONTAL &&
1633              constraints.fill != GridBagConstraints.BOTH)
1634             && (r.width > (constraints.minWidth + constraints.ipadx))) {
1635             diffx = r.width - (constraints.minWidth + constraints.ipadx);
1636             r.width = constraints.minWidth + constraints.ipadx;
1637         }
1638 
1639         diffy = 0;
1640         if ((constraints.fill != GridBagConstraints.VERTICAL &&
1641              constraints.fill != GridBagConstraints.BOTH)
1642             && (r.height > (constraints.minHeight + constraints.ipady))) {
1643             diffy = r.height - (constraints.minHeight + constraints.ipady);
1644             r.height = constraints.minHeight + constraints.ipady;
1645         }
1646 
1647         switch (constraints.anchor) {
1648           case GridBagConstraints.BASELINE:
1649               r.x += diffx/2;
1650               alignOnBaseline(constraints, r, cellY, cellHeight);
1651               break;
1652           case GridBagConstraints.BASELINE_LEADING:
1653               if (rightToLeft) {
1654                   r.x += diffx;
1655               }
1656               alignOnBaseline(constraints, r, cellY, cellHeight);
1657               break;
1658           case GridBagConstraints.BASELINE_TRAILING:
1659               if (!rightToLeft) {
1660                   r.x += diffx;
1661               }
1662               alignOnBaseline(constraints, r, cellY, cellHeight);
1663               break;
1664           case GridBagConstraints.ABOVE_BASELINE:
1665               r.x += diffx/2;
1666               alignAboveBaseline(constraints, r, cellY, cellHeight);
1667               break;
1668           case GridBagConstraints.ABOVE_BASELINE_LEADING:
1669               if (rightToLeft) {
1670                   r.x += diffx;
1671               }
1672               alignAboveBaseline(constraints, r, cellY, cellHeight);
1673               break;
1674           case GridBagConstraints.ABOVE_BASELINE_TRAILING:
1675               if (!rightToLeft) {
1676                   r.x += diffx;
1677               }
1678               alignAboveBaseline(constraints, r, cellY, cellHeight);
1679               break;
1680           case GridBagConstraints.BELOW_BASELINE:
1681               r.x += diffx/2;
1682               alignBelowBaseline(constraints, r, cellY, cellHeight);
1683               break;
1684           case GridBagConstraints.BELOW_BASELINE_LEADING:
1685               if (rightToLeft) {
1686                   r.x += diffx;
1687               }
1688               alignBelowBaseline(constraints, r, cellY, cellHeight);
1689               break;
1690           case GridBagConstraints.BELOW_BASELINE_TRAILING:
1691               if (!rightToLeft) {
1692                   r.x += diffx;
1693               }
1694               alignBelowBaseline(constraints, r, cellY, cellHeight);
1695               break;
1696           case GridBagConstraints.CENTER:
1697               r.x += diffx/2;
1698               r.y += diffy/2;
1699               break;
1700           case GridBagConstraints.PAGE_START:
1701           case GridBagConstraints.NORTH:
1702               r.x += diffx/2;
1703               break;
1704           case GridBagConstraints.NORTHEAST:
1705               r.x += diffx;
1706               break;
1707           case GridBagConstraints.EAST:
1708               r.x += diffx;
1709               r.y += diffy/2;
1710               break;
1711           case GridBagConstraints.SOUTHEAST:
1712               r.x += diffx;
1713               r.y += diffy;
1714               break;
1715           case GridBagConstraints.PAGE_END:
1716           case GridBagConstraints.SOUTH:
1717               r.x += diffx/2;
1718               r.y += diffy;
1719               break;
1720           case GridBagConstraints.SOUTHWEST:
1721               r.y += diffy;
1722               break;
1723           case GridBagConstraints.WEST:
1724               r.y += diffy/2;
1725               break;
1726           case GridBagConstraints.NORTHWEST:
1727               break;
1728           case GridBagConstraints.LINE_START:
1729               if (rightToLeft) {
1730                   r.x += diffx;
1731               }
1732               r.y += diffy/2;
1733               break;
1734           case GridBagConstraints.LINE_END:
1735               if (!rightToLeft) {
1736                   r.x += diffx;
1737               }
1738               r.y += diffy/2;
1739               break;
1740           case GridBagConstraints.FIRST_LINE_START:
1741               if (rightToLeft) {
1742                   r.x += diffx;
1743               }
1744               break;
1745           case GridBagConstraints.FIRST_LINE_END:
1746               if (!rightToLeft) {
1747                   r.x += diffx;
1748               }
1749               break;
1750           case GridBagConstraints.LAST_LINE_START:
1751               if (rightToLeft) {
1752                   r.x += diffx;
1753               }
1754               r.y += diffy;
1755               break;
1756           case GridBagConstraints.LAST_LINE_END:
1757               if (!rightToLeft) {
1758                   r.x += diffx;
1759               }
1760               r.y += diffy;
1761               break;
1762           default:
1763               throw new IllegalArgumentException("illegal anchor value");
1764         }
1765     }
1766 
1767     /**
1768      * Positions on the baseline.
1769      *
1770      * @param cellY the location of the row, does not include insets
1771      * @param cellHeight the height of the row, does not take into account
1772      *        insets
1773      * @param r available bounds for the component, is padded by insets and
1774      *        ipady
1775      */
1776     private void alignOnBaseline(GridBagConstraints cons, Rectangle r,
1777                                  int cellY, int cellHeight) {
1778         if (cons.ascent >= 0) {
1779             if (cons.baselineResizeBehavior == Component.
1780                     BaselineResizeBehavior.CONSTANT_DESCENT) {
1781                 // Anchor to the bottom.
1782                 // Baseline is at (cellY + cellHeight - maxDescent).
1783                 // Bottom of component (maxY) is at baseline + descent
1784                 // of component. We need to subtract the bottom inset here
1785                 // as the descent in the constraints object includes the
1786                 // bottom inset.
1787                 int maxY = cellY + cellHeight -
1788                       layoutInfo.maxDescent[cons.tempY + cons.tempHeight - 1] +
1789                       cons.descent - cons.insets.bottom;
1790                 if (!cons.isVerticallyResizable()) {
1791                     // Component not resizable, calculate y location
1792                     // from maxY - height.
1793                     r.y = maxY - cons.minHeight;
1794                     r.height = cons.minHeight;
1795                 } else {
1796                     // Component is resizable. As brb is constant descent,
1797                     // can expand component to fill region above baseline.
1798                     // Subtract out the top inset so that components insets
1799                     // are honored.
1800                     r.height = maxY - cellY - cons.insets.top;
1801                 }
1802             }
1803             else {
1804                 // BRB is not constant_descent
1805                 int baseline; // baseline for the row, relative to cellY
1806                 // Component baseline, includes insets.top
1807                 int ascent = cons.ascent;
1808                 if (layoutInfo.hasConstantDescent(cons.tempY)) {
1809                     // Mixed ascent/descent in same row, calculate position
1810                     // off maxDescent
1811                     baseline = cellHeight - layoutInfo.maxDescent[cons.tempY];
1812                 }
1813                 else {
1814                     // Only ascents/unknown in this row, anchor to top
1815                     baseline = layoutInfo.maxAscent[cons.tempY];
1816                 }
1817                 if (cons.baselineResizeBehavior == Component.
1818                         BaselineResizeBehavior.OTHER) {
1819                     // BRB is other, which means we can only determine
1820                     // the baseline by asking for it again giving the
1821                     // size we plan on using for the component.
1822                     boolean fits = false;
1823                     ascent = componentAdjusting.getBaseline(r.width, r.height);
1824                     if (ascent >= 0) {
1825                         // Component has a baseline, pad with top inset
1826                         // (this follows from calculateBaseline which
1827                         // does the same).
1828                         ascent += cons.insets.top;
1829                     }
1830                     if (ascent >= 0 && ascent <= baseline) {
1831                         // Components baseline fits within rows baseline.
1832                         // Make sure the descent fits within the space as well.
1833                         if (baseline + (r.height - ascent - cons.insets.top) <=
1834                                 cellHeight - cons.insets.bottom) {
1835                             // It fits, we're good.
1836                             fits = true;
1837                         }
1838                         else if (cons.isVerticallyResizable()) {
1839                             // Doesn't fit, but it's resizable.  Try
1840                             // again assuming we'll get ascent again.
1841                             int ascent2 = componentAdjusting.getBaseline(
1842                                     r.width, cellHeight - cons.insets.bottom -
1843                                     baseline + ascent);
1844                             if (ascent2 >= 0) {
1845                                 ascent2 += cons.insets.top;
1846                             }
1847                             if (ascent2 >= 0 && ascent2 <= ascent) {
1848                                 // It'll fit
1849                                 r.height = cellHeight - cons.insets.bottom -
1850                                         baseline + ascent;
1851                                 ascent = ascent2;
1852                                 fits = true;
1853                             }
1854                         }
1855                     }
1856                     if (!fits) {
1857                         // Doesn't fit, use min size and original ascent
1858                         ascent = cons.ascent;
1859                         r.width = cons.minWidth;
1860                         r.height = cons.minHeight;
1861                     }
1862                 }
1863                 // Reset the components y location based on
1864                 // components ascent and baseline for row. Because ascent
1865                 // includes the baseline
1866                 r.y = cellY + baseline - ascent + cons.insets.top;
1867                 if (cons.isVerticallyResizable()) {
1868                     switch(cons.baselineResizeBehavior) {
1869                     case CONSTANT_ASCENT:
1870                         r.height = Math.max(cons.minHeight,cellY + cellHeight -
1871                                             r.y - cons.insets.bottom);
1872                         break;
1873                     case CENTER_OFFSET:
1874                         {
1875                             int upper = r.y - cellY - cons.insets.top;
1876                             int lower = cellY + cellHeight - r.y -
1877                                 cons.minHeight - cons.insets.bottom;
1878                             int delta = Math.min(upper, lower);
1879                             delta += delta;
1880                             if (delta > 0 &&
1881                                 (cons.minHeight + cons.centerPadding +
1882                                  delta) / 2 + cons.centerOffset != baseline) {
1883                                 // Off by 1
1884                                 delta--;
1885                             }
1886                             r.height = cons.minHeight + delta;
1887                             r.y = cellY + baseline -
1888                                 (r.height + cons.centerPadding) / 2 -
1889                                 cons.centerOffset;
1890                         }
1891                         break;
1892                     case OTHER:
1893                         // Handled above
1894                         break;
1895                     default:
1896                         break;
1897                     }
1898                 }
1899             }
1900         }
1901         else {
1902             centerVertically(cons, r, cellHeight);
1903         }
1904     }
1905 
1906     /**
1907      * Positions the specified component above the baseline. That is
1908      * the bottom edge of the component will be aligned along the baseline.
1909      * If the row does not have a baseline, this centers the component.
1910      */
1911     private void alignAboveBaseline(GridBagConstraints cons, Rectangle r,
1912                                     int cellY, int cellHeight) {
1913         if (layoutInfo.hasBaseline(cons.tempY)) {
1914             int maxY; // Baseline for the row
1915             if (layoutInfo.hasConstantDescent(cons.tempY)) {
1916                 // Prefer descent
1917                 maxY = cellY + cellHeight - layoutInfo.maxDescent[cons.tempY];
1918             }
1919             else {
1920                 // Prefer ascent
1921                 maxY = cellY + layoutInfo.maxAscent[cons.tempY];
1922             }
1923             if (cons.isVerticallyResizable()) {
1924                 // Component is resizable. Top edge is offset by top
1925                 // inset, bottom edge on baseline.
1926                 r.y = cellY + cons.insets.top;
1927                 r.height = maxY - r.y;
1928             }
1929             else {
1930                 // Not resizable.
1931                 r.height = cons.minHeight + cons.ipady;
1932                 r.y = maxY - r.height;
1933             }
1934         }
1935         else {
1936             centerVertically(cons, r, cellHeight);
1937         }
1938     }
1939 
1940     /**
1941      * Positions below the baseline.
1942      */
1943     private void alignBelowBaseline(GridBagConstraints cons, Rectangle r,
1944                                     int cellY, int cellHeight) {
1945         if (layoutInfo.hasBaseline(cons.tempY)) {
1946             if (layoutInfo.hasConstantDescent(cons.tempY)) {
1947                 // Prefer descent
1948                 r.y = cellY + cellHeight - layoutInfo.maxDescent[cons.tempY];
1949             }
1950             else {
1951                 // Prefer ascent
1952                 r.y = cellY + layoutInfo.maxAscent[cons.tempY];
1953             }
1954             if (cons.isVerticallyResizable()) {
1955                 r.height = cellY + cellHeight - r.y - cons.insets.bottom;
1956             }
1957         }
1958         else {
1959             centerVertically(cons, r, cellHeight);
1960         }
1961     }
1962 
1963     private void centerVertically(GridBagConstraints cons, Rectangle r,
1964                                   int cellHeight) {
1965         if (!cons.isVerticallyResizable()) {
1966             r.y += Math.max(0, (cellHeight - cons.insets.top -
1967                                 cons.insets.bottom - cons.minHeight -
1968                                 cons.ipady) / 2);
1969         }
1970     }
1971 
1972     /**
1973      * Figures out the minimum size of the
1974      * master based on the information from <code>getLayoutInfo</code>.
1975      * This method should only be used internally by
1976      * <code>GridBagLayout</code>.
1977      *
1978      * @param parent the layout container
1979      * @param info the layout info for this parent
1980      * @return a <code>Dimension</code> object containing the
1981      *   minimum size
1982      * @since 1.4
1983      */
1984     protected Dimension getMinSize(Container parent, GridBagLayoutInfo info) {
1985         return GetMinSize(parent, info);
1986     }
1987 
1988     /**
1989      * This method is obsolete and supplied for backwards
1990      * compatability only; new code should call {@link
1991      * #getMinSize(java.awt.Container, GridBagLayoutInfo) getMinSize} instead.
1992      * This method is the same as <code>getMinSize</code>;
1993      * refer to <code>getMinSize</code> for details on parameters
1994      * and return value.
1995      */
1996     protected Dimension GetMinSize(Container parent, GridBagLayoutInfo info) {
1997         Dimension d = new Dimension();
1998         int i, t;
1999         Insets insets = parent.getInsets();
2000 
2001         t = 0;
2002         for(i = 0; i < info.width; i++)
2003             t += info.minWidth[i];
2004         d.width = t + insets.left + insets.right;
2005 
2006         t = 0;
2007         for(i = 0; i < info.height; i++)
2008             t += info.minHeight[i];
2009         d.height = t + insets.top + insets.bottom;
2010 
2011         return d;
2012     }
2013 
2014     transient boolean rightToLeft = false;
2015 
2016     /**
2017      * Lays out the grid.
2018      * This method should only be used internally by
2019      * <code>GridBagLayout</code>.
2020      *
2021      * @param parent the layout container
2022      * @since 1.4
2023      */
2024     protected void arrangeGrid(Container parent) {
2025         ArrangeGrid(parent);
2026     }
2027 
2028     /**
2029      * This method is obsolete and supplied for backwards
2030      * compatability only; new code should call {@link
2031      * #arrangeGrid(Container) arrangeGrid} instead.
2032      * This method is the same as <code>arrangeGrid</code>;
2033      * refer to <code>arrangeGrid</code> for details on the
2034      * parameter.
2035      */
2036     protected void ArrangeGrid(Container parent) {
2037         Component comp;
2038         int compindex;
2039         GridBagConstraints constraints;
2040         Insets insets = parent.getInsets();
2041         Component components[] = parent.getComponents();
2042         Dimension d;
2043         Rectangle r = new Rectangle();
2044         int i, diffw, diffh;
2045         double weight;
2046         GridBagLayoutInfo info;
2047 
2048         rightToLeft = !parent.getComponentOrientation().isLeftToRight();
2049 
2050         /*
2051          * If the parent has no slaves anymore, then don't do anything
2052          * at all:  just leave the parent's size as-is.
2053          */
2054         if (components.length == 0 &&
2055             (columnWidths == null || columnWidths.length == 0) &&
2056             (rowHeights == null || rowHeights.length == 0)) {
2057             return;
2058         }
2059 
2060         /*
2061          * Pass #1: scan all the slaves to figure out the total amount
2062          * of space needed.
2063          */
2064 
2065         info = getLayoutInfo(parent, PREFERREDSIZE);
2066         d = getMinSize(parent, info);
2067 
2068         if (parent.width < d.width || parent.height < d.height) {
2069             info = getLayoutInfo(parent, MINSIZE);
2070             d = getMinSize(parent, info);
2071         }
2072 
2073         layoutInfo = info;
2074         r.width = d.width;
2075         r.height = d.height;
2076 
2077         /*
2078          * DEBUG
2079          *
2080          * DumpLayoutInfo(info);
2081          * for (compindex = 0 ; compindex < components.length ; compindex++) {
2082          * comp = components[compindex];
2083          * if (!comp.isVisible())
2084          *      continue;
2085          * constraints = lookupConstraints(comp);
2086          * DumpConstraints(constraints);
2087          * }
2088          * System.out.println("minSize " + r.width + " " + r.height);
2089          */
2090 
2091         /*
2092          * If the current dimensions of the window don't match the desired
2093          * dimensions, then adjust the minWidth and minHeight arrays
2094          * according to the weights.
2095          */
2096 
2097         diffw = parent.width - r.width;
2098         if (diffw != 0) {
2099             weight = 0.0;
2100             for (i = 0; i < info.width; i++)
2101                 weight += info.weightX[i];
2102             if (weight > 0.0) {
2103                 for (i = 0; i < info.width; i++) {
2104                     int dx = (int)(( ((double)diffw) * info.weightX[i]) / weight);
2105                     info.minWidth[i] += dx;
2106                     r.width += dx;
2107                     if (info.minWidth[i] < 0) {
2108                         r.width -= info.minWidth[i];
2109                         info.minWidth[i] = 0;
2110                     }
2111                 }
2112             }
2113             diffw = parent.width - r.width;
2114         }
2115 
2116         else {
2117             diffw = 0;
2118         }
2119 
2120         diffh = parent.height - r.height;
2121         if (diffh != 0) {
2122             weight = 0.0;
2123             for (i = 0; i < info.height; i++)
2124                 weight += info.weightY[i];
2125             if (weight > 0.0) {
2126                 for (i = 0; i < info.height; i++) {
2127                     int dy = (int)(( ((double)diffh) * info.weightY[i]) / weight);
2128                     info.minHeight[i] += dy;
2129                     r.height += dy;
2130                     if (info.minHeight[i] < 0) {
2131                         r.height -= info.minHeight[i];
2132                         info.minHeight[i] = 0;
2133                     }
2134                 }
2135             }
2136             diffh = parent.height - r.height;
2137         }
2138 
2139         else {
2140             diffh = 0;
2141         }
2142 
2143         /*
2144          * DEBUG
2145          *
2146          * System.out.println("Re-adjusted:");
2147          * DumpLayoutInfo(info);
2148          */
2149 
2150         /*
2151          * Now do the actual layout of the slaves using the layout information
2152          * that has been collected.
2153          */
2154 
2155         info.startx = diffw/2 + insets.left;
2156         info.starty = diffh/2 + insets.top;
2157 
2158         for (compindex = 0 ; compindex < components.length ; compindex++) {
2159             comp = components[compindex];
2160             if (!comp.isVisible()){
2161                 continue;
2162             }
2163             constraints = lookupConstraints(comp);
2164 
2165             if (!rightToLeft) {
2166                 r.x = info.startx;
2167                 for(i = 0; i < constraints.tempX; i++)
2168                     r.x += info.minWidth[i];
2169             } else {
2170                 r.x = parent.width - (diffw/2 + insets.right);
2171                 for(i = 0; i < constraints.tempX; i++)
2172                     r.x -= info.minWidth[i];
2173             }
2174 
2175             r.y = info.starty;
2176             for(i = 0; i < constraints.tempY; i++)
2177                 r.y += info.minHeight[i];
2178 
2179             r.width = 0;
2180             for(i = constraints.tempX;
2181                 i < (constraints.tempX + constraints.tempWidth);
2182                 i++) {
2183                 r.width += info.minWidth[i];
2184             }
2185 
2186             r.height = 0;
2187             for(i = constraints.tempY;
2188                 i < (constraints.tempY + constraints.tempHeight);
2189                 i++) {
2190                 r.height += info.minHeight[i];
2191             }
2192 
2193             componentAdjusting = comp;
2194             adjustForGravity(constraints, r);
2195 
2196             /* fix for 4408108 - components were being created outside of the container */
2197             /* fix for 4969409 "-" replaced by "+"  */
2198             if (r.x < 0) {
2199                 r.width += r.x;
2200                 r.x = 0;
2201             }
2202 
2203             if (r.y < 0) {
2204                 r.height += r.y;
2205                 r.y = 0;
2206             }
2207 
2208             /*
2209              * If the window is too small to be interesting then
2210              * unmap it.  Otherwise configure it and then make sure
2211              * it's mapped.
2212              */
2213 
2214             if ((r.width <= 0) || (r.height <= 0)) {
2215                 comp.setBounds(0, 0, 0, 0);
2216             }
2217             else {
2218                 if (comp.x != r.x || comp.y != r.y ||
2219                     comp.width != r.width || comp.height != r.height) {
2220                     comp.setBounds(r.x, r.y, r.width, r.height);
2221                 }
2222             }
2223         }
2224     }
2225 
2226     // Added for serial backwards compatability (4348425)
2227     static final long serialVersionUID = 8838754796412211005L;
2228 }