Home » openjdk-7 » java » awt » [javadoc | source]

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

Home » openjdk-7 » java » awt » [javadoc | source]