home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / GridBagLayout.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  41.3 KB  |  1,334 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)GridBagLayout.java    1.32 98/09/04
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.util.Hashtable;
  17. import java.util.Vector;
  18.  
  19. class GridBagLayoutInfo implements java.io.Serializable {
  20.   int width, height;        /* number of cells horizontally, vertically */
  21.   int startx, starty;        /* starting point for layout */
  22.   int minWidth[];        /* largest minWidth in each column */
  23.   int minHeight[];        /* largest minHeight in each row */
  24.   double weightX[];        /* largest weight in each column */
  25.   double weightY[];        /* largest weight in each row */
  26.  
  27.   GridBagLayoutInfo () {
  28.     minWidth = new int[GridBagLayout.MAXGRIDSIZE];
  29.     minHeight = new int[GridBagLayout.MAXGRIDSIZE];
  30.     weightX = new double[GridBagLayout.MAXGRIDSIZE];
  31.     weightY = new double[GridBagLayout.MAXGRIDSIZE];
  32.   }
  33. }
  34.  
  35. /**
  36.  * The <code>GridBagLayout</code> class is a flexible layout
  37.  * manager that aligns components vertically and horizontally,
  38.  * without requiring that the components be of the same size.
  39.  * Each <code>GridBagLayout</code> object maintains a dynamic
  40.  * rectangular grid of cells, with each component occupying
  41.  * one or more cells, called its <em>display area</em>.
  42.  * <p>
  43.  * Each component managed by a grid bag layout is associated
  44.  * with an instance of
  45.  * {@link GridBagConstraints}
  46.  * that specifies how the component is laid out within its display area.
  47.  * <p>
  48.  * How a <code>GridBagLayout</code> object places a set of components
  49.  * depends on the <code>GridBagConstraints</code> object associated
  50.  * with each component, and on the minimum size
  51.  * and the preferred size of the components' containers.
  52.  * <p>
  53.  * To use a grid bag layout effectively, you must customize one or more
  54.  * of the <code>GridBagConstraints</code> objects that are associated
  55.  * with its components. You customize a <code>GridBagConstraints</code>
  56.  * object by setting one or more of its instance variables:
  57.  * <p>
  58.  * <dl>
  59.  * <dt>{@link GridBagConstraints#gridx},
  60.  * {@link GridBagConstraints#gridy}
  61.  * <dd>Specifies the cell at the upper left of the component's display area,
  62.  * where the upper-left-most cell has address
  63.  * <code>gridx = 0</code>,
  64.  * <code>gridy = 0</code>.
  65.  * Use <code>GridBagConstraints.RELATIVE</code> (the default value)
  66.  * to specify that the component be just placed
  67.  * just to the right of (for <code>gridx</code>)
  68.  * or just below (for <code>gridy</code>)
  69.  * the component that was added to the container
  70.  * just before this component was added.
  71.  * <dt>{@link GridBagConstraints#gridwidth},
  72.  * {@link GridBagConstraints#gridheight}
  73.  * <dd>Specifies the number of cells in a row (for <code>gridwidth</code>)
  74.  * or column (for <code>gridheight</code>)
  75.  * in the component's display area.
  76.  * The default value is 1.
  77.  * Use <code>GridBagConstraints.REMAINDER</code> to specify
  78.  * that the component be the last one in its row (for <code>gridwidth</code>)
  79.  * or column (for <code>gridheight</code>).
  80.  * Use <code>GridBagConstraints.RELATIVE</code> to specify
  81.  * that the component be the next to last one
  82.  * in its row (for <code>gridwidth</code>)
  83.  * or column (for <code>gridheight</code>).
  84.  * <dt>{@link GridBagConstraints#fill}
  85.  * <dd>Used when the component's display area
  86.  * is larger than the component's requested size
  87.  * to determine whether (and how) to resize the component.
  88.  * Possible values are
  89.  * <code>GridBagConstraints.NONE</code> (the default),
  90.  * <code>GridBagConstraints.HORIZONTAL</code>
  91.  * (make the component wide enough to fill its display area
  92.  * horizontally, but don't change its height),
  93.  * <code>GridBagConstraints.VERTICAL</code>
  94.  * (make the component tall enough to fill its display area
  95.  * vertically, but don't change its width), and
  96.  * <code>GridBagConstraints.BOTH</code>
  97.  * (make the component fill its display area entirely).
  98.  * <dt>{@link GridBagConstraints#ipadx},
  99.  * {@link GridBagConstraints#ipady}
  100.  * <dd>Specifies the component's internal padding within the layout,
  101.  * how much to add to the minimum size of the component.
  102.  * The width of the component will be at least its minimum width
  103.  * plus <code>(ipadx * 2)</code> pixels (since the padding
  104.  * applies to both sides of the component). Similarly, the height of
  105.  * the component will be at least the minimum height plus
  106.  * <code>(ipady * 2)</code> pixels.
  107.  * <dt>{@link GridBagConstraints#insets}
  108.  * <dd>Specifies the component's external padding, the minimum
  109.  * amount of space between the component and the edges of its display area.
  110.  * <dt>{@link GridBagConstraints#anchor}
  111.  * <dd>Used when the component is smaller than its display area
  112.  * to determine where (within the display area) to place the component.
  113.  * Valid values are
  114.  * <code>GridBagConstraints.CENTER</code> (the default),
  115.  * <code>GridBagConstraints.NORTH</code>,
  116.  * <code>GridBagConstraints.NORTHEAST</code>,
  117.  * <code>GridBagConstraints.EAST</code>,
  118.  * <code>GridBagConstraints.SOUTHEAST</code>,
  119.  * <code>GridBagConstraints.SOUTH</code>,
  120.  * <code>GridBagConstraints.SOUTHWEST</code>,
  121.  * <code>GridBagConstraints.WEST</code>, and
  122.  * <code>GridBagConstraints.NORTHWEST</code>.
  123.  * <dt>{@link GridBagConstraints#weightx},
  124.  * {@link GridBagConstraints#weighty}
  125.  * <dd>Used to determine how to distribute space, which is
  126.  * important for specifying resizing behavior.
  127.  * Unless you specify a weight for at least one component
  128.  * in a row (<code>weightx</code>) and column (<code>weighty</code>),
  129.  * all the components clump together in the center of their container.
  130.  * This is because when the weight is zero (the default),
  131.  * the <code>GridBagLayout</code> object puts any extra space
  132.  * between its grid of cells and the edges of the container.
  133.  * </dl>
  134.  * <p>
  135.  * The following figure shows ten components (all buttons)
  136.  * managed by a grid bag layout:
  137.  * <p>
  138.  * <img src="doc-files/GridBagLayout-1.gif"
  139.  * ALIGN=center HSPACE=10 VSPACE=7>
  140.  * <p>
  141.  * Each of the ten components has the <code>fill</code> field
  142.  * of its associated <code>GridBagConstraints</code> object
  143.  * set to <code>GridBagConstraints.BOTH</code>.
  144.  * In addition, the components have the following non-default constraints:
  145.  * <p>
  146.  * <ul>
  147.  * <li>Button1, Button2, Button3: <code>weightx = 1.0</code>
  148.  * <li>Button4: <code>weightx = 1.0</code>,
  149.  * <code>gridwidth = GridBagConstraints.REMAINDER</code>
  150.  * <li>Button5: <code>gridwidth = GridBagConstraints.REMAINDER</code>
  151.  * <li>Button6: <code>gridwidth = GridBagConstraints.RELATIVE</code>
  152.  * <li>Button7: <code>gridwidth = GridBagConstraints.REMAINDER</code>
  153.  * <li>Button8: <code>gridheight = 2</code>,
  154.  * <code>weighty = 1.0</code>
  155.  * <li>Button9, Button 10:
  156.  * <code>gridwidth = GridBagConstraints.REMAINDER</code>
  157.  * </ul>
  158.  * <p>
  159.  * Here is the code that implements the example shown above:
  160.  * <p>
  161.  * <hr><blockquote><pre>
  162.  * import java.awt.*;
  163.  * import java.util.*;
  164.  * import java.applet.Applet;
  165.  *
  166.  * public class GridBagEx1 extends Applet {
  167.  *
  168.  *     protected void makebutton(String name,
  169.  *                               GridBagLayout gridbag,
  170.  *                               GridBagConstraints c) {
  171.  *         Button button = new Button(name);
  172.  *         gridbag.setConstraints(button, c);
  173.  *         add(button);
  174.  *     }
  175.  *
  176.  *     public void init() {
  177.  *         GridBagLayout gridbag = new GridBagLayout();
  178.  *         GridBagConstraints c = new GridBagConstraints();
  179.  *
  180.  *         setFont(new Font("Helvetica", Font.PLAIN, 14));
  181.  *         setLayout(gridbag);
  182.  *
  183.  *         c.fill = GridBagConstraints.BOTH;
  184.  *         c.weightx = 1.0;
  185.  *         makebutton("Button1", gridbag, c);
  186.  *         makebutton("Button2", gridbag, c);
  187.  *         makebutton("Button3", gridbag, c);
  188.  *
  189.  *            c.gridwidth = GridBagConstraints.REMAINDER; //end row
  190.  *         makebutton("Button4", gridbag, c);
  191.  *
  192.  *         c.weightx = 0.0;           //reset to the default
  193.  *         makebutton("Button5", gridbag, c); //another row
  194.  *
  195.  *        c.gridwidth = GridBagConstraints.RELATIVE; //next-to-last in row
  196.  *         makebutton("Button6", gridbag, c);
  197.  *
  198.  *        c.gridwidth = GridBagConstraints.REMAINDER; //end row
  199.  *         makebutton("Button7", gridbag, c);
  200.  *
  201.  *        c.gridwidth = 1;              //reset to the default
  202.  *        c.gridheight = 2;
  203.  *         c.weighty = 1.0;
  204.  *         makebutton("Button8", gridbag, c);
  205.  *
  206.  *         c.weighty = 0.0;           //reset to the default
  207.  *        c.gridwidth = GridBagConstraints.REMAINDER; //end row
  208.  *        c.gridheight = 1;           //reset to the default
  209.  *         makebutton("Button9", gridbag, c);
  210.  *         makebutton("Button10", gridbag, c);
  211.  *
  212.  *         setSize(300, 100);
  213.  *     }
  214.  *
  215.  *     public static void main(String args[]) {
  216.  *        Frame f = new Frame("GridBag Layout Example");
  217.  *        GridBagEx1 ex1 = new GridBagEx1();
  218.  *
  219.  *        ex1.init();
  220.  *
  221.  *        f.add("Center", ex1);
  222.  *        f.pack();
  223.  *        f.setSize(f.getPreferredSize());
  224.  *        f.show();
  225.  *     }
  226.  * }
  227.  * </pre></blockquote><hr>
  228.  * <p>
  229.  * @version 1.5, 16 Nov 1995
  230.  * @author Doug Stein
  231.  * @see       java.awt.GridBagConstraints
  232.  * @since     JDK1.0
  233.  */
  234. public class GridBagLayout implements LayoutManager2,
  235.                       java.io.Serializable {
  236.  
  237.     /**
  238.      * The maximum number of grid positions (both horizontally and
  239.      * vertically) that can be laid out by the grid bag layout.
  240.      */
  241.   protected static final int MAXGRIDSIZE = 512;
  242.  
  243.     /**
  244.      * The smallest grid that can be laid out by the grid bag layout.
  245.      */
  246.   protected static final int MINSIZE = 1;
  247.   protected static final int PREFERREDSIZE = 2;
  248.  
  249.     /**
  250.      * This hashtable maintains the association between
  251.      * a component and its gridbag constraints.
  252.      * The Keys in comptable are the components and the
  253.      * values are the instances of GridBagConstraints.
  254.      *
  255.      * @serial
  256.      * @see java.awt.GridBagConstraints
  257.      */
  258.   protected Hashtable comptable;
  259.  
  260.     /**
  261.      * This field holds a gridbag constraints instance
  262.      * containing the default values, so if a component
  263.      * does not have gridbag constraints associated with
  264.      * it, then the component will be assigned a
  265.      * copy of the <code>defaultConstraints</code>.
  266.      *
  267.      * @serial
  268.      * @see getConstraints()
  269.      * @see setConstraints()
  270.      * @see lookupConstraints()
  271.      */
  272.   protected GridBagConstraints defaultConstraints;
  273.  
  274.     /**
  275.      * This field holds tha layout information
  276.      * for the gridbag.  The information in this field
  277.      * is based on the most recent validation of the
  278.      * gridbag.
  279.      * If <code>layoutInfo</code> is <code>null</code>
  280.      * this indicates that there are no components in
  281.      * the gridbag or if there are components, they have
  282.      * not yet been validated.
  283.      *
  284.      * @serial
  285.      * @see GetLayoutInfo()
  286.      */
  287.   protected GridBagLayoutInfo layoutInfo;
  288.  
  289.     /**
  290.      * This field holds the overrides to the column minimum
  291.      * width.  If this field is non-null the values are
  292.      * applied to the gridbag after all of the minimum columns
  293.      * widths have been calculated.
  294.      * If columnWidths has more elements than the number of
  295.      * columns, columns are added to the gridbag to match
  296.      * the number of elements in columnWidth.
  297.      *
  298.      * @serial
  299.      * @see getLayoutDimensions()
  300.      */
  301.   public int columnWidths[];
  302.   
  303.    /**
  304.      * This field holds the overrides to the row minimum
  305.      * heights.  If this field is non-null the values are
  306.      * applied to the gridbag after all of the minimum row
  307.      * heights have been calculated.
  308.      * If rowHeights has more elements than the number of
  309.      * rows, rowa are added to the gridbag to match
  310.      * the number of elements in rowHeights.
  311.      *
  312.      * @serial
  313.      * @see getLayoutDimensions()
  314.      */
  315.   public int rowHeights[];
  316.  
  317.     /**
  318.      * This field holds the overrides to the column weights.
  319.      * If this field is non-null the values are
  320.      * applied to the gridbag after all of the columns
  321.      * weights have been calculated.
  322.      * If columnWeights[i] > then weight for column i, then
  323.      * column i is assigned the weight in columnWeights[i].
  324.      * If columnWeights has more elements than the number
  325.      * of columns, the excess elements are ignored - they do
  326.      * not cause more columns to be created.
  327.      *
  328.      * @serial
  329.      * @see
  330.      */
  331.   public double columnWeights[];
  332.  
  333.     /**
  334.      * This field holds the overrides to the row weights.
  335.      * If this field is non-null the values are
  336.      * applied to the gridbag after all of the rows
  337.      * weights have been calculated.
  338.      * If rowWeights[i] > then weight for row i, then
  339.      * row i is assigned the weight in rowWeights[i].
  340.      * If rowWeights has more elements than the number
  341.      * of rows, the excess elements are ignored - they do
  342.      * not cause more rows to be created.
  343.      *
  344.      * @serial
  345.      * @see
  346.      */
  347.   public double rowWeights[];
  348.  
  349.   /**
  350.    * Creates a grid bag layout manager.
  351.    */
  352.   public GridBagLayout () {
  353.     comptable = new Hashtable();
  354.     defaultConstraints = new GridBagConstraints();
  355.   }
  356.  
  357.   /**
  358.    * Sets the constraints for the specified component in this layout.
  359.    * @param       comp the component to be modified.
  360.    * @param       constraints the constraints to be applied.
  361.    */
  362.   public void setConstraints(Component comp, GridBagConstraints constraints) {
  363.     comptable.put(comp, constraints.clone());
  364.   }
  365.  
  366.   /**
  367.    * Gets the constraints for the specified component.  A copy of
  368.    * the actual <code>GridBagConstraints</code> object is returned.
  369.    * @param       comp the component to be queried.
  370.    * @return      the constraint for the specified component in this
  371.    *                  grid bag layout; a copy of the actual constraint
  372.    *                  object is returned.
  373.    */
  374.   public GridBagConstraints getConstraints(Component comp) {
  375.     GridBagConstraints constraints = (GridBagConstraints)comptable.get(comp);
  376.     if (constraints == null) {
  377.       setConstraints(comp, defaultConstraints);
  378.       constraints = (GridBagConstraints)comptable.get(comp);
  379.     }
  380.     return (GridBagConstraints)constraints.clone();
  381.   }
  382.  
  383.   /**
  384.    * Retrieves the constraints for the specified component.
  385.    * The return value is not a copy, but is the actual
  386.    * <code>GridBagConstraints</code> object used by the layout mechanism.
  387.    * @param       comp the component to be queried
  388.    * @return      the contraints for the specified component.
  389.    */
  390.   protected GridBagConstraints lookupConstraints(Component comp) {
  391.     GridBagConstraints constraints = (GridBagConstraints)comptable.get(comp);
  392.     if (constraints == null) {
  393.       setConstraints(comp, defaultConstraints);
  394.       constraints = (GridBagConstraints)comptable.get(comp);
  395.     }
  396.     return constraints;
  397.   }
  398.  
  399.     /**
  400.      * Determines the origin of the layout grid.
  401.      * Most applications do not call this method directly.
  402.      * @return     the origin of the cell in the top-left
  403.      *                    corner of the layout grid.
  404.      * @since      JDK1.1
  405.      */
  406.   public Point getLayoutOrigin () {
  407.     Point origin = new Point(0,0);
  408.     if (layoutInfo != null) {
  409.       origin.x = layoutInfo.startx;
  410.       origin.y = layoutInfo.starty;
  411.     }
  412.     return origin;
  413.   }
  414.  
  415.     /**
  416.      * Determines column widths and row heights for the layout grid.
  417.      * <p>
  418.      * Most applications do not call this method directly.
  419.      * @return     an array of two arrays, containing the widths
  420.      *                       of the layout columns and
  421.      *                       the heights of the layout rows.
  422.      * @since      JDK1.1
  423.      */
  424.   public int [][] getLayoutDimensions () {
  425.     if (layoutInfo == null)
  426.       return new int[2][0];
  427.  
  428.     int dim[][] = new int [2][];
  429.     dim[0] = new int[layoutInfo.width];
  430.     dim[1] = new int[layoutInfo.height];
  431.  
  432.     System.arraycopy(layoutInfo.minWidth, 0, dim[0], 0, layoutInfo.width);
  433.     System.arraycopy(layoutInfo.minHeight, 0, dim[1], 0, layoutInfo.height);
  434.  
  435.     return dim;
  436.   }
  437.  
  438.     /**
  439.      * Determines the weights of the layout grid's columns and rows.
  440.      * Weights are used to calculate how much a given column or row
  441.      * stretches beyond its preferred size, if the layout has extra
  442.      * room to fill.
  443.      * <p>
  444.      * Most applications do not call this method directly.
  445.      * @return      an array of two arrays, representing the
  446.      *                    horizontal weights of the layout columns
  447.      *                    and the vertical weights of the layout rows.
  448.      * @since       JDK1.1
  449.      */
  450.   public double [][] getLayoutWeights () {
  451.     if (layoutInfo == null)
  452.       return new double[2][0];
  453.  
  454.     double weights[][] = new double [2][];
  455.     weights[0] = new double[layoutInfo.width];
  456.     weights[1] = new double[layoutInfo.height];
  457.  
  458.     System.arraycopy(layoutInfo.weightX, 0, weights[0], 0, layoutInfo.width);
  459.     System.arraycopy(layoutInfo.weightY, 0, weights[1], 0, layoutInfo.height);
  460.  
  461.     return weights;
  462.   }
  463.  
  464.     /**
  465.      * Determines which cell in the layout grid contains the point
  466.      * specified by <code>(x, y)</code>. Each cell is identified
  467.      * by its column index (ranging from 0 to the number of columns
  468.      * minus 1) and its row index (ranging from 0 to the number of
  469.      * rows minus 1).
  470.      * <p>
  471.      * If the <code>(x, y)</code> point lies
  472.      * outside the grid, the following rules are used.
  473.      * The column index is returned as zero if <code>x</code> lies to the
  474.      * left of the layout, and as the number of columns if <code>x</code> lies
  475.      * to the right of the layout. The row index is returned as zero
  476.      * if <code>y</code> lies above the layout,
  477.      * and as the number of rows if <code>y</code> lies
  478.      * below the layout.
  479.      * @param      x    the <i>x</i> coordinate of a point.
  480.      * @param      y    the <i>y</i> coordinate of a point.
  481.      * @return     an ordered pair of indexes that indicate which cell
  482.      *             in the layout grid contains the point
  483.      *             (<i>x</i>, <i>y</i>).
  484.      * @since      JDK1.1
  485.      */
  486.   public Point location(int x, int y) {
  487.     Point loc = new Point(0,0);
  488.     int i, d;
  489.  
  490.     if (layoutInfo == null)
  491.       return loc;
  492.  
  493.     d = layoutInfo.startx;
  494.     for (i=0; i<layoutInfo.width; i++) {
  495.       d += layoutInfo.minWidth[i];
  496.       if (d > x)
  497.     break;
  498.     }
  499.     loc.x = i;
  500.  
  501.     d = layoutInfo.starty;
  502.     for (i=0; i<layoutInfo.height; i++) {
  503.       d += layoutInfo.minHeight[i];
  504.       if (d > y)
  505.     break;
  506.     }
  507.     loc.y = i;
  508.  
  509.     return loc;
  510.   }
  511.  
  512.   /**
  513.    * Adds the specified component with the specified name to the layout.
  514.    * @param      name         the name of the component.
  515.    * @param      comp         the component to be added.
  516.    */
  517.   public void addLayoutComponent(String name, Component comp) {
  518.   }
  519.  
  520.     /**
  521.      * Adds the specified component to the layout, using the specified
  522.      * constraint object.
  523.      * @param      comp         the component to be added.
  524.      * @param      constraints  an object that determines how
  525.      *                              the component is added to the layout.
  526.      */
  527.     public void addLayoutComponent(Component comp, Object constraints) {
  528.       if (constraints instanceof GridBagConstraints) {
  529.         setConstraints(comp, (GridBagConstraints)constraints);
  530.     } else if (constraints != null) {
  531.         throw new IllegalArgumentException("cannot add to layout: constraint must be a GridBagConstraint");
  532.     }
  533.     }
  534.  
  535.   /**
  536.      * Removes the specified component from this layout.
  537.      * <p>
  538.      * Most applications do not call this method directly.
  539.      * @param    comp   the component to be removed.
  540.      * @see      java.awt.Container#remove(java.awt.Component)
  541.      * @see      java.awt.Container#removeAll()
  542.    */
  543.   public void removeLayoutComponent(Component comp) {
  544.   }
  545.  
  546.   /**
  547.      * Determines the preferred size of the <code>target</code>
  548.      * container using this grid bag layout.
  549.      * <p>
  550.      * Most applications do not call this method directly.
  551.      * @param     target   the container in which to do the layout.
  552.      * @see       java.awt.Container#getPreferredSize
  553.    */
  554.   public Dimension preferredLayoutSize(Container parent) {
  555.     GridBagLayoutInfo info = GetLayoutInfo(parent, PREFERREDSIZE);
  556.     return GetMinSize(parent, info);
  557.   }
  558.  
  559.   /**
  560.      * Determines the minimum size of the <code>target</code> container
  561.      * using this grid bag layout.
  562.      * <p>
  563.      * Most applications do not call this method directly.
  564.      * @param     target   the container in which to do the layout.
  565.      * @see       java.awt.Container#doLayout
  566.    */
  567.   public Dimension minimumLayoutSize(Container parent) {
  568.     GridBagLayoutInfo info = GetLayoutInfo(parent, MINSIZE);
  569.     return GetMinSize(parent, info);
  570.   }
  571.  
  572.     /**
  573.      * Returns the maximum dimensions for this layout given the components
  574.      * in the specified target container.
  575.      * @param target the component which needs to be laid out
  576.      * @see Container
  577.      * @see #minimumLayoutSize
  578.      * @see #preferredLayoutSize
  579.      */
  580.     public Dimension maximumLayoutSize(Container target) {
  581.     return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  582.     }
  583.  
  584.     /**
  585.      * Returns the alignment along the x axis.  This specifies how
  586.      * the component would like to be aligned relative to other
  587.      * components.  The value should be a number between 0 and 1
  588.      * where 0 represents alignment along the origin, 1 is aligned
  589.      * the furthest away from the origin, 0.5 is centered, etc.
  590.      */
  591.     public float getLayoutAlignmentX(Container parent) {
  592.     return 0.5f;
  593.     }
  594.  
  595.     /**
  596.      * Returns the alignment along the y axis.  This specifies how
  597.      * the component would like to be aligned relative to other
  598.      * components.  The value should be a number between 0 and 1
  599.      * where 0 represents alignment along the origin, 1 is aligned
  600.      * the furthest away from the origin, 0.5 is centered, etc.
  601.      */
  602.     public float getLayoutAlignmentY(Container parent) {
  603.     return 0.5f;
  604.     }
  605.  
  606.     /**
  607.      * Invalidates the layout, indicating that if the layout manager
  608.      * has cached information it should be discarded.
  609.      */
  610.     public void invalidateLayout(Container target) {
  611.     }
  612.  
  613.   /**
  614.    * Lays out the specified container using this grid bag layout.
  615.    * This method reshapes components in the specified container in
  616.    * order to satisfy the contraints of this <code>GridBagLayout</code>
  617.    * object.
  618.    * <p>
  619.    * Most applications do not call this method directly.
  620.    * @param parent the container in which to do the layout.
  621.    * @see java.awt.Container
  622.    * @see java.awt.Container#doLayout
  623.    */
  624.   public void layoutContainer(Container parent) {
  625.     ArrangeGrid(parent);
  626.   }
  627.  
  628.   /**
  629.      * Returns a string representation of this grid bag layout's values.
  630.      * @return     a string representation of this grid bag layout.
  631.    */
  632.   public String toString() {
  633.     return getClass().getName();
  634.   }
  635.  
  636.   /**
  637.    * Print the layout information.  Useful for debugging.
  638.    */
  639.  
  640.   /* DEBUG
  641.    *
  642.    *  protected void DumpLayoutInfo(GridBagLayoutInfo s) {
  643.    *    int x;
  644.    *
  645.    *    System.out.println("Col\tWidth\tWeight");
  646.    *    for (x=0; x<s.width; x++) {
  647.    *      System.out.println(x + "\t" +
  648.    *             s.minWidth[x] + "\t" +
  649.    *             s.weightX[x]);
  650.    *    }
  651.    *    System.out.println("Row\tHeight\tWeight");
  652.    *    for (x=0; x<s.height; x++) {
  653.    *      System.out.println(x + "\t" +
  654.    *             s.minHeight[x] + "\t" +
  655.    *             s.weightY[x]);
  656.    *    }
  657.    *  }
  658.    */
  659.  
  660.   /**
  661.    * Print the layout constraints.  Useful for debugging.
  662.    */
  663.  
  664.   /* DEBUG
  665.    *
  666.    *  protected void DumpConstraints(GridBagConstraints constraints) {
  667.    *    System.out.println(
  668.    *               "wt " +
  669.    *               constraints.weightx +
  670.    *               " " +
  671.    *               constraints.weighty +
  672.    *               ", " +
  673.    *
  674.    *               "box " +
  675.    *               constraints.gridx +
  676.    *               " " +
  677.    *               constraints.gridy +
  678.    *               " " +
  679.    *               constraints.gridwidth +
  680.    *               " " +
  681.    *               constraints.gridheight +
  682.    *               ", " +
  683.    *
  684.    *               "min " +
  685.    *               constraints.minWidth +
  686.    *               " " +
  687.    *               constraints.minHeight +
  688.    *               ", " +
  689.    *
  690.    *               "pad " +
  691.    *               constraints.insets.bottom +
  692.    *               " " +
  693.    *               constraints.insets.left +
  694.    *               " " +
  695.    *               constraints.insets.right +
  696.    *               " " +
  697.    *               constraints.insets.top +
  698.    *               " " +
  699.    *               constraints.ipadx +
  700.    *               " " +
  701.    *               constraints.ipady);
  702.    *  }
  703.    */
  704.  
  705.   /*
  706.    * Fill in an instance of the above structure for the current set
  707.    * of managed children.  This requires three passes through the
  708.    * set of children:
  709.    *
  710.    * 1) Figure out the dimensions of the layout grid
  711.    * 2) Determine which cells the components occupy
  712.    * 3) Distribute the weights and min sizes amoung the rows/columns.
  713.    *
  714.    * This also caches the minsizes for all the children when they are
  715.    * first encountered (so subsequent loops don't need to ask again).
  716.    */
  717.  
  718.   protected GridBagLayoutInfo GetLayoutInfo(Container parent, int sizeflag) {
  719.    synchronized (parent.getTreeLock()) {
  720.     GridBagLayoutInfo r = new GridBagLayoutInfo();
  721.     Component comp;
  722.     GridBagConstraints constraints;
  723.     Dimension d;
  724.     Component components[] = parent.getComponents();
  725.  
  726.     int compindex, i, j, k, px, py, pixels_diff, nextSize;
  727.     int curX, curY, curWidth, curHeight, curRow, curCol;
  728.     double weight_diff, weight, start, size;
  729.     int xMax[], yMax[];
  730.  
  731.     /*
  732.      * Pass #1
  733.      *
  734.      * Figure out the dimensions of the layout grid (use a value of 1 for
  735.      * zero or negative widths and heights).
  736.      */
  737.  
  738.     r.width = r.height = 0;
  739.     curRow = curCol = -1;
  740.     xMax = new int[MAXGRIDSIZE];
  741.     yMax = new int[MAXGRIDSIZE];
  742.  
  743.     for (compindex = 0 ; compindex < components.length ; compindex++) {
  744.       comp = components[compindex];
  745.       if (!comp.isVisible())
  746.     continue;
  747.       constraints = lookupConstraints(comp);
  748.  
  749.       curX = constraints.gridx;
  750.       curY = constraints.gridy;
  751.       curWidth = constraints.gridwidth;
  752.       if (curWidth <= 0)
  753.     curWidth = 1;
  754.       curHeight = constraints.gridheight;
  755.       if (curHeight <= 0)
  756.     curHeight = 1;
  757.  
  758.       /* If x or y is negative, then use relative positioning: */
  759.       if (curX < 0 && curY < 0) {
  760.     if (curRow >= 0)
  761.       curY = curRow;
  762.     else if (curCol >= 0)
  763.       curX = curCol;
  764.     else
  765.       curY = 0;
  766.       }
  767.       if (curX < 0) {
  768.     px = 0;
  769.     for (i = curY; i < (curY + curHeight); i++)
  770.       px = Math.max(px, xMax[i]);
  771.  
  772.     curX = px - curX - 1;
  773.     if(curX < 0)
  774.       curX = 0;
  775.       }
  776.       else if (curY < 0) {
  777.     py = 0;
  778.     for (i = curX; i < (curX + curWidth); i++)
  779.       py = Math.max(py, yMax[i]);
  780.  
  781.     curY = py - curY - 1;
  782.     if(curY < 0)
  783.       curY = 0;
  784.       }
  785.  
  786.       /* Adjust the grid width and height */
  787.       for (px = curX + curWidth; r.width < px; r.width++);
  788.       for (py = curY + curHeight; r.height < py; r.height++);
  789.  
  790.       /* Adjust the xMax and yMax arrays */
  791.       for (i = curX; i < (curX + curWidth); i++) { yMax[i] = py; }
  792.       for (i = curY; i < (curY + curHeight); i++) { xMax[i] = px; }
  793.  
  794.       /* Cache the current slave's size. */
  795.       if (sizeflag == PREFERREDSIZE)
  796.     d = comp.getPreferredSize();
  797.       else
  798.     d = comp.getMinimumSize();
  799.       constraints.minWidth = d.width;
  800.       constraints.minHeight = d.height;
  801.  
  802.       /* Zero width and height must mean that this is the last item (or
  803.        * else something is wrong). */
  804.       if (constraints.gridheight == 0 && constraints.gridwidth == 0)
  805.     curRow = curCol = -1;
  806.  
  807.       /* Zero width starts a new row */
  808.       if (constraints.gridheight == 0 && curRow < 0)
  809.     curCol = curX + curWidth;
  810.  
  811.       /* Zero height starts a new column */
  812.       else if (constraints.gridwidth == 0 && curCol < 0)
  813.     curRow = curY + curHeight;
  814.     }
  815.  
  816.     /*
  817.      * Apply minimum row/column dimensions
  818.      */
  819.     if (columnWidths != null && r.width < columnWidths.length)
  820.       r.width = columnWidths.length;
  821.     if (rowHeights != null && r.height < rowHeights.length)
  822.       r.height = rowHeights.length;
  823.  
  824.     /*
  825.      * Pass #2
  826.      *
  827.      * Negative values for gridX are filled in with the current x value.
  828.      * Negative values for gridY are filled in with the current y value.
  829.      * Negative or zero values for gridWidth and gridHeight end the current
  830.      *  row or column, respectively.
  831.      */
  832.  
  833.     curRow = curCol = -1;
  834.     xMax = new int[MAXGRIDSIZE];
  835.     yMax = new int[MAXGRIDSIZE];
  836.  
  837.     for (compindex = 0 ; compindex < components.length ; compindex++) {
  838.       comp = components[compindex];
  839.       if (!comp.isVisible())
  840.     continue;
  841.       constraints = lookupConstraints(comp);
  842.  
  843.       curX = constraints.gridx;
  844.       curY = constraints.gridy;
  845.       curWidth = constraints.gridwidth;
  846.       curHeight = constraints.gridheight;
  847.  
  848.       /* If x or y is negative, then use relative positioning: */
  849.       if (curX < 0 && curY < 0) {
  850.     if(curRow >= 0)
  851.       curY = curRow;
  852.     else if(curCol >= 0)
  853.       curX = curCol;
  854.     else
  855.       curY = 0;
  856.       }
  857.  
  858.       if (curX < 0) {
  859.     if (curHeight <= 0) {
  860.       curHeight += r.height - curY;
  861.       if (curHeight < 1)
  862.         curHeight = 1;
  863.     }
  864.  
  865.     px = 0;
  866.     for (i = curY; i < (curY + curHeight); i++)
  867.       px = Math.max(px, xMax[i]);
  868.  
  869.     curX = px - curX - 1;
  870.     if(curX < 0)
  871.       curX = 0;
  872.       }
  873.       else if (curY < 0) {
  874.     if (curWidth <= 0) {
  875.       curWidth += r.width - curX;
  876.       if (curWidth < 1)
  877.         curWidth = 1;
  878.     }
  879.  
  880.     py = 0;
  881.     for (i = curX; i < (curX + curWidth); i++)
  882.       py = Math.max(py, yMax[i]);
  883.  
  884.     curY = py - curY - 1;
  885.     if(curY < 0)
  886.       curY = 0;
  887.       }
  888.  
  889.       if (curWidth <= 0) {
  890.     curWidth += r.width - curX;
  891.     if (curWidth < 1)
  892.       curWidth = 1;
  893.       }
  894.  
  895.       if (curHeight <= 0) {
  896.     curHeight += r.height - curY;
  897.     if (curHeight < 1)
  898.       curHeight = 1;
  899.       }
  900.  
  901.       px = curX + curWidth;
  902.       py = curY + curHeight;
  903.  
  904.       for (i = curX; i < (curX + curWidth); i++) { yMax[i] = py; }
  905.       for (i = curY; i < (curY + curHeight); i++) { xMax[i] = px; }
  906.  
  907.       /* Make negative sizes start a new row/column */
  908.       if (constraints.gridheight == 0 && constraints.gridwidth == 0)
  909.     curRow = curCol = -1;
  910.       if (constraints.gridheight == 0 && curRow < 0)
  911.     curCol = curX + curWidth;
  912.       else if (constraints.gridwidth == 0 && curCol < 0)
  913.         curRow = curY + curHeight;
  914.  
  915.       /* Assign the new values to the gridbag slave */
  916.       constraints.tempX = curX;
  917.       constraints.tempY = curY;
  918.       constraints.tempWidth = curWidth;
  919.       constraints.tempHeight = curHeight;
  920.     }
  921.  
  922.     /*
  923.      * Apply minimum row/column dimensions and weights
  924.      */
  925.     if (columnWidths != null)
  926.       System.arraycopy(columnWidths, 0, r.minWidth, 0, columnWidths.length);
  927.     if (rowHeights != null)
  928.       System.arraycopy(rowHeights, 0, r.minHeight, 0, rowHeights.length);
  929.     if (columnWeights != null)
  930.       System.arraycopy(columnWeights, 0, r.weightX, 0, columnWeights.length);
  931.     if (rowWeights != null)
  932.       System.arraycopy(rowWeights, 0, r.weightY, 0, rowWeights.length);
  933.  
  934.     /*
  935.      * Pass #3
  936.      *
  937.      * Distribute the minimun widths and weights:
  938.      */
  939.  
  940.     nextSize = Integer.MAX_VALUE;
  941.  
  942.     for (i = 1;
  943.      i != Integer.MAX_VALUE;
  944.      i = nextSize, nextSize = Integer.MAX_VALUE) {
  945.       for (compindex = 0 ; compindex < components.length ; compindex++) {
  946.     comp = components[compindex];
  947.     if (!comp.isVisible())
  948.       continue;
  949.     constraints = lookupConstraints(comp);
  950.  
  951.     if (constraints.tempWidth == i) {
  952.       px = constraints.tempX + constraints.tempWidth; /* right column */
  953.  
  954.       /*
  955.        * Figure out if we should use this slave\'s weight.  If the weight
  956.        * is less than the total weight spanned by the width of the cell,
  957.        * then discard the weight.  Otherwise split the difference
  958.        * according to the existing weights.
  959.        */
  960.  
  961.       weight_diff = constraints.weightx;
  962.       for (k = constraints.tempX; k < px; k++)
  963.         weight_diff -= r.weightX[k];
  964.       if (weight_diff > 0.0) {
  965.         weight = 0.0;
  966.         for (k = constraints.tempX; k < px; k++)
  967.           weight += r.weightX[k];
  968.         for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
  969.           double wt = r.weightX[k];
  970.           double dx = (wt * weight_diff) / weight;
  971.           r.weightX[k] += dx;
  972.           weight_diff -= dx;
  973.           weight -= wt;
  974.         }
  975.         /* Assign the remainder to the rightmost cell */
  976.         r.weightX[px-1] += weight_diff;
  977.       }
  978.  
  979.       /*
  980.        * Calculate the minWidth array values.
  981.        * First, figure out how wide the current slave needs to be.
  982.        * Then, see if it will fit within the current minWidth values.
  983.        * If it will not fit, add the difference according to the
  984.        * weightX array.
  985.        */
  986.  
  987.       pixels_diff =
  988.         constraints.minWidth + constraints.ipadx +
  989.         constraints.insets.left + constraints.insets.right;
  990.  
  991.       for (k = constraints.tempX; k < px; k++)
  992.         pixels_diff -= r.minWidth[k];
  993.       if (pixels_diff > 0) {
  994.         weight = 0.0;
  995.         for (k = constraints.tempX; k < px; k++)
  996.           weight += r.weightX[k];
  997.         for (k = constraints.tempX; weight > 0.0 && k < px; k++) {
  998.           double wt = r.weightX[k];
  999.           int dx = (int)((wt * ((double)pixels_diff)) / weight);
  1000.           r.minWidth[k] += dx;
  1001.           pixels_diff -= dx;
  1002.           weight -= wt;
  1003.         }
  1004.         /* Any leftovers go into the rightmost cell */
  1005.         r.minWidth[px-1] += pixels_diff;
  1006.       }
  1007.     }
  1008.     else if (constraints.tempWidth > i && constraints.tempWidth < nextSize)
  1009.       nextSize = constraints.tempWidth;
  1010.  
  1011.  
  1012.     if (constraints.tempHeight == i) {
  1013.       py = constraints.tempY + constraints.tempHeight; /* bottom row */
  1014.  
  1015.       /*
  1016.        * Figure out if we should use this slave\'s weight.  If the weight
  1017.        * is less than the total weight spanned by the height of the cell,
  1018.        * then discard the weight.  Otherwise split it the difference
  1019.        * according to the existing weights.
  1020.        */
  1021.  
  1022.       weight_diff = constraints.weighty;
  1023.       for (k = constraints.tempY; k < py; k++)
  1024.         weight_diff -= r.weightY[k];
  1025.       if (weight_diff > 0.0) {
  1026.         weight = 0.0;
  1027.         for (k = constraints.tempY; k < py; k++)
  1028.           weight += r.weightY[k];
  1029.         for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
  1030.           double wt = r.weightY[k];
  1031.           double dy = (wt * weight_diff) / weight;
  1032.           r.weightY[k] += dy;
  1033.           weight_diff -= dy;
  1034.           weight -= wt;
  1035.         }
  1036.         /* Assign the remainder to the bottom cell */
  1037.         r.weightY[py-1] += weight_diff;
  1038.       }
  1039.  
  1040.       /*
  1041.        * Calculate the minHeight array values.
  1042.        * First, figure out how tall the current slave needs to be.
  1043.        * Then, see if it will fit within the current minHeight values.
  1044.        * If it will not fit, add the difference according to the
  1045.        * weightY array.
  1046.        */
  1047.  
  1048.       pixels_diff =
  1049.         constraints.minHeight + constraints.ipady +
  1050.         constraints.insets.top + constraints.insets.bottom;
  1051.       for (k = constraints.tempY; k < py; k++)
  1052.         pixels_diff -= r.minHeight[k];
  1053.       if (pixels_diff > 0) {
  1054.         weight = 0.0;
  1055.         for (k = constraints.tempY; k < py; k++)
  1056.           weight += r.weightY[k];
  1057.         for (k = constraints.tempY; weight > 0.0 && k < py; k++) {
  1058.           double wt = r.weightY[k];
  1059.           int dy = (int)((wt * ((double)pixels_diff)) / weight);
  1060.           r.minHeight[k] += dy;
  1061.           pixels_diff -= dy;
  1062.           weight -= wt;
  1063.         }
  1064.         /* Any leftovers go into the bottom cell */
  1065.         r.minHeight[py-1] += pixels_diff;
  1066.       }
  1067.     }
  1068.     else if (constraints.tempHeight > i &&
  1069.          constraints.tempHeight < nextSize)
  1070.       nextSize = constraints.tempHeight;
  1071.       }
  1072.     }
  1073.  
  1074.     return r;
  1075.    }
  1076.   }
  1077.  
  1078.   /*
  1079.    * Adjusts the x, y, width, and height fields to the correct
  1080.    * values depending on the constraint geometry and pads.
  1081.    */
  1082.   protected void AdjustForGravity(GridBagConstraints constraints,
  1083.                   Rectangle r) {
  1084.     int diffx, diffy;
  1085.  
  1086.     r.x += constraints.insets.left;
  1087.     r.width -= (constraints.insets.left + constraints.insets.right);
  1088.     r.y += constraints.insets.top;
  1089.     r.height -= (constraints.insets.top + constraints.insets.bottom);
  1090.  
  1091.     diffx = 0;
  1092.     if ((constraints.fill != GridBagConstraints.HORIZONTAL &&
  1093.      constraints.fill != GridBagConstraints.BOTH)
  1094.     && (r.width > (constraints.minWidth + constraints.ipadx))) {
  1095.       diffx = r.width - (constraints.minWidth + constraints.ipadx);
  1096.       r.width = constraints.minWidth + constraints.ipadx;
  1097.     }
  1098.  
  1099.     diffy = 0;
  1100.     if ((constraints.fill != GridBagConstraints.VERTICAL &&
  1101.      constraints.fill != GridBagConstraints.BOTH)
  1102.     && (r.height > (constraints.minHeight + constraints.ipady))) {
  1103.       diffy = r.height - (constraints.minHeight + constraints.ipady);
  1104.       r.height = constraints.minHeight + constraints.ipady;
  1105.     }
  1106.  
  1107.     switch (constraints.anchor) {
  1108.     case GridBagConstraints.CENTER:
  1109.       r.x += diffx/2;
  1110.       r.y += diffy/2;
  1111.       break;
  1112.     case GridBagConstraints.NORTH:
  1113.       r.x += diffx/2;
  1114.       break;
  1115.     case GridBagConstraints.NORTHEAST:
  1116.       r.x += diffx;
  1117.       break;
  1118.     case GridBagConstraints.EAST:
  1119.       r.x += diffx;
  1120.       r.y += diffy/2;
  1121.       break;
  1122.     case GridBagConstraints.SOUTHEAST:
  1123.       r.x += diffx;
  1124.       r.y += diffy;
  1125.       break;
  1126.     case GridBagConstraints.SOUTH:
  1127.       r.x += diffx/2;
  1128.       r.y += diffy;
  1129.       break;
  1130.     case GridBagConstraints.SOUTHWEST:
  1131.       r.y += diffy;
  1132.       break;
  1133.     case GridBagConstraints.WEST:
  1134.       r.y += diffy/2;
  1135.       break;
  1136.     case GridBagConstraints.NORTHWEST:
  1137.       break;
  1138.     default:
  1139.       throw new IllegalArgumentException("illegal anchor value");
  1140.     }
  1141.   }
  1142.  
  1143.   /*
  1144.    * Figure out the minimum size of the
  1145.    * master based on the information from GetLayoutInfo()
  1146.    */
  1147.   protected Dimension GetMinSize(Container parent, GridBagLayoutInfo info) {
  1148.     Dimension d = new Dimension();
  1149.     int i, t;
  1150.     Insets insets = parent.getInsets();
  1151.  
  1152.     t = 0;
  1153.     for(i = 0; i < info.width; i++)
  1154.       t += info.minWidth[i];
  1155.     d.width = t + insets.left + insets.right;
  1156.  
  1157.     t = 0;
  1158.     for(i = 0; i < info.height; i++)
  1159.       t += info.minHeight[i];
  1160.     d.height = t + insets.top + insets.bottom;
  1161.  
  1162.     return d;
  1163.   }
  1164.  
  1165.   /*
  1166.    * Lay out the grid
  1167.    */
  1168.   protected void ArrangeGrid(Container parent) {
  1169.     Component comp;
  1170.     int compindex;
  1171.     GridBagConstraints constraints;
  1172.     Insets insets = parent.getInsets();
  1173.     Component components[] = parent.getComponents();
  1174.     Dimension d;
  1175.     Rectangle r = new Rectangle();
  1176.     int i, diffw, diffh;
  1177.     double weight;
  1178.     GridBagLayoutInfo info;
  1179.  
  1180.     /*
  1181.      * If the parent has no slaves anymore, then don't do anything
  1182.      * at all:  just leave the parent's size as-is.
  1183.      */
  1184.     if (components.length == 0 &&
  1185.     (columnWidths == null || columnWidths.length == 0) &&
  1186.     (rowHeights == null || rowHeights.length == 0)) {
  1187.       return;
  1188.     }
  1189.  
  1190.     /*
  1191.      * Pass #1: scan all the slaves to figure out the total amount
  1192.      * of space needed.
  1193.      */
  1194.  
  1195.     info = GetLayoutInfo(parent, PREFERREDSIZE);
  1196.     d = GetMinSize(parent, info);
  1197.  
  1198.     if (parent.width < d.width || parent.height < d.height) {
  1199.       info = GetLayoutInfo(parent, MINSIZE);
  1200.       d = GetMinSize(parent, info);
  1201.     }
  1202.  
  1203.     layoutInfo = info;
  1204.     r.width = d.width;
  1205.     r.height = d.height;
  1206.  
  1207.     /*
  1208.      * DEBUG
  1209.      *
  1210.      * DumpLayoutInfo(info);
  1211.      * for (compindex = 0 ; compindex < components.length ; compindex++) {
  1212.      * comp = components[compindex];
  1213.      * if (!comp.isVisible())
  1214.      *    continue;
  1215.      * constraints = lookupConstraints(comp);
  1216.      * DumpConstraints(constraints);
  1217.      * }
  1218.      * System.out.println("minSize " + r.width + " " + r.height);
  1219.      */
  1220.  
  1221.     /*
  1222.      * If the current dimensions of the window don't match the desired
  1223.      * dimensions, then adjust the minWidth and minHeight arrays
  1224.      * according to the weights.
  1225.      */
  1226.  
  1227.     diffw = parent.width - r.width;
  1228.     if (diffw != 0) {
  1229.       weight = 0.0;
  1230.       for (i = 0; i < info.width; i++)
  1231.     weight += info.weightX[i];
  1232.       if (weight > 0.0) {
  1233.     for (i = 0; i < info.width; i++) {
  1234.       int dx = (int)(( ((double)diffw) * info.weightX[i]) / weight);
  1235.       info.minWidth[i] += dx;
  1236.       r.width += dx;
  1237.       if (info.minWidth[i] < 0) {
  1238.         r.width -= info.minWidth[i];
  1239.         info.minWidth[i] = 0;
  1240.       }
  1241.     }
  1242.       }
  1243.       diffw = parent.width - r.width;
  1244.     }
  1245.     else {
  1246.       diffw = 0;
  1247.     }
  1248.  
  1249.     diffh = parent.height - r.height;
  1250.     if (diffh != 0) {
  1251.       weight = 0.0;
  1252.       for (i = 0; i < info.height; i++)
  1253.     weight += info.weightY[i];
  1254.       if (weight > 0.0) {
  1255.     for (i = 0; i < info.height; i++) {
  1256.       int dy = (int)(( ((double)diffh) * info.weightY[i]) / weight);
  1257.       info.minHeight[i] += dy;
  1258.       r.height += dy;
  1259.       if (info.minHeight[i] < 0) {
  1260.         r.height -= info.minHeight[i];
  1261.         info.minHeight[i] = 0;
  1262.       }
  1263.     }
  1264.       }
  1265.       diffh = parent.height - r.height;
  1266.     }
  1267.     else {
  1268.       diffh = 0;
  1269.     }
  1270.  
  1271.     /*
  1272.      * DEBUG
  1273.      *
  1274.      * System.out.println("Re-adjusted:");
  1275.      * DumpLayoutInfo(info);
  1276.      */
  1277.  
  1278.     /*
  1279.      * Now do the actual layout of the slaves using the layout information
  1280.      * that has been collected.
  1281.      */
  1282.  
  1283.     info.startx = diffw/2 + insets.left;
  1284.     info.starty = diffh/2 + insets.top;
  1285.  
  1286.     for (compindex = 0 ; compindex < components.length ; compindex++) {
  1287.       comp = components[compindex];
  1288.       if (!comp.isVisible())
  1289.     continue;
  1290.       constraints = lookupConstraints(comp);
  1291.  
  1292.       r.x = info.startx;
  1293.       for(i = 0; i < constraints.tempX; i++)
  1294.     r.x += info.minWidth[i];
  1295.  
  1296.       r.y = info.starty;
  1297.       for(i = 0; i < constraints.tempY; i++)
  1298.     r.y += info.minHeight[i];
  1299.  
  1300.       r.width = 0;
  1301.       for(i = constraints.tempX;
  1302.       i < (constraints.tempX + constraints.tempWidth);
  1303.       i++) {
  1304.     r.width += info.minWidth[i];
  1305.       }
  1306.  
  1307.       r.height = 0;
  1308.       for(i = constraints.tempY;
  1309.       i < (constraints.tempY + constraints.tempHeight);
  1310.       i++) {
  1311.     r.height += info.minHeight[i];
  1312.       }
  1313.  
  1314.       AdjustForGravity(constraints, r);
  1315.  
  1316.       /*
  1317.        * If the window is too small to be interesting then
  1318.        * unmap it.  Otherwise configure it and then make sure
  1319.        * it's mapped.
  1320.        */
  1321.  
  1322.       if ((r.width <= 0) || (r.height <= 0)) {
  1323.     comp.setBounds(0, 0, 0, 0);
  1324.       }
  1325.       else {
  1326.     if (comp.x != r.x || comp.y != r.y ||
  1327.         comp.width != r.width || comp.height != r.height) {
  1328.       comp.setBounds(r.x, r.y, r.width, r.height);
  1329.     }
  1330.       }
  1331.     }
  1332.   }
  1333. }
  1334.