home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / GridBagLayout.java < prev    next >
Text File  |  1997-10-01  |  42KB  |  1,262 lines

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