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