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