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