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