Mega Code Archive

 
Categories / Java / Swing JFC
 

Basically two (or more) columns of different, but constant, widths

/*  * Copyright (c) Ian F. Darwin, http://www.darwinsys.com/, 1996-2002.  * All rights reserved. Software written by Ian F. Darwin and others.  * $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $  *  * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  *  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  * POSSIBILITY OF SUCH DAMAGE.  *   * Java, the Duke mascot, and all variants of Sun's Java "steaming coffee  * cup" logo are trademarks of Sun Microsystems. Sun's, and James Gosling's,  * pioneering role in inventing and promulgating (and standardizing) the Java   * language and environment is gratefully acknowledged.  *   * The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for  * inventing predecessor languages C and C++ is also gratefully acknowledged.  */ import java.awt.*; /**  * A simple layout manager, for "Entry" areas ith e.g., a list of labels and  * their corresponding JTextFields. These typically look like:  *   * <PRE>  *   * Login:    _______________   * Password: _______________  *   * </PRE>  *   * Basically two (or more) columns of different, but constant, widths. <b>Note:  * all columns must be the same height! </b>.  * <P>  * Construct instances by passing an array of the column width percentages (as  * doubles, fractions from 0.1 to 0.9, so 40%,60% would be {0.4, 0.6}). The  * length of this array uniquely determines the number of columns. Columns are  * forced to be the relevant widths. <b>Note: </b> As with GridLayout, the  * number of items added <B>must </B> be an even multiple of the number of  * columns. If not, exceptions may be thrown!  *   * @author Ian F. Darwin, http://www.darwinsys.com/  * @version $Id: EntryLayout.java,v 1.11 2004/06/01 02:51:37 ian Exp $  */ public class EntryLayout implements LayoutManager {   /** The array of widths, as decimal fractions (0.4 == 40%, etc.). */   protected final double[] widthPercentages;   /** The number of columns. */   protected final int COLUMNS;   /** The default padding */   protected final static int HPAD = 5, VPAD = 5;   /** The actual padding */   protected final int hpad, vpad;   /** True if the list of widths was valid. */   protected boolean validWidths = false;   /**    * Construct an EntryLayout with widths and padding specified.    *     * @param relWidths    *            Array of doubles specifying relative column widths.    * @param h    *            Horizontal padding between items    * @param v    *            Vertical padding between items    */   public EntryLayout(double[] relWidths, int h, int v) {     COLUMNS = relWidths.length;     widthPercentages = new double[COLUMNS];     for (int i = 0; i < relWidths.length; i++) {       if (relWidths[i] >= 1.0)         throw new IllegalArgumentException(             "EntryLayout: widths must be fractions < 1");       widthPercentages[i] = relWidths[i];     }     validWidths = true;     hpad = h;     vpad = v;   }   /**    * Construct an EntryLayout with widths and with default padding amounts.    *     * @param relWidths    *            Array of doubles specifying column widths.    */   public EntryLayout(double[] relWidths) {     this(relWidths, HPAD, VPAD);   }   /**    * Adds the specified component with the specified constraint to the layout;    * required by LayoutManager but not used.    */   public void addLayoutComponent(String name, Component comp) {     // nothing to do   }   /**    * Removes the specified component from the layout; required by    * LayoutManager, but does nothing.    */   public void removeLayoutComponent(Component comp) {     // nothing to do   }   /**    * Calculates the preferred size dimensions for the specified panel given    * the components in the specified parent container.    */   public Dimension preferredLayoutSize(Container parent) {     // System.out.println("preferredLayoutSize");     return computeLayoutSize(parent, hpad, vpad);   }   /**    * Find the minimum Dimension for the specified container given the    * components therein.    */   public Dimension minimumLayoutSize(Container parent) {     // System.out.println("minimumLayoutSize");     return computeLayoutSize(parent, 0, 0);   }   /** The width of each column, as found by computLayoutSize(). */   int[] widths;   /** The height of each row, as found by computLayoutSize(). */   int[] heights;   /**    * Compute the size of the whole mess. Serves as the guts of    * preferredLayoutSize() and minimumLayoutSize().    *     * @param parent    *            The container in which to do the layout.    * @param hp    *            The horizontal padding (may be zero)    * @param vp    *            The Vertical Padding (may be zero).    */   protected Dimension computeLayoutSize(Container parent, int hp, int vp) {     if (!validWidths)       return null;     Component[] components = parent.getComponents();     Dimension contSize = parent.getSize();     int preferredWidth = 0, preferredHeight = 0;     widths = new int[COLUMNS];     heights = new int[components.length / COLUMNS];     // System.out.println("Grid: " + widths.length + ", " + heights.length);     int i;     // Pass One: Compute largest widths and heights.     for (i = 0; i < components.length; i++) {       int row = i / widthPercentages.length;       int col = i % widthPercentages.length;       Component c = components[i];       Dimension d = c.getPreferredSize();       widths[col] = Math.max(widths[col], d.width);       heights[row] = Math.max(heights[row], d.height);     }     // Pass two: agregate them.     for (i = 0; i < widths.length; i++)       preferredWidth += widths[i] + hp;     for (i = 0; i < heights.length; i++)       preferredHeight += heights[i] + vp;     // Finally, pass the sums back as the actual size.     return new Dimension(preferredWidth, preferredHeight);   }   /**    * Lays out the container in the specified panel. This is a row-column type    * layout; find x, y, width and height of each Component.    *     * @param parent    *            The Container whose children we are laying out.    */   public void layoutContainer(Container parent) {          if (!validWidths)       return;     Component[] components = parent.getComponents();     Dimension contSize = parent.getSize();     int x = 0;     for (int i = 0; i < components.length; i++) {       int row = i / COLUMNS;       int col = i % COLUMNS;       Component c = components[i];       Dimension d = c.getPreferredSize();       int colWidth = (int) (contSize.width * widthPercentages[col]);       if (col == 0) {         x = hpad;       } else {         x += hpad * (col - 1)             + (int) (contSize.width * widthPercentages[col - 1]);       }       int y = vpad * (row) + (row * heights[row])           + (heights[row] - d.height);       Rectangle r = new Rectangle(x, y, colWidth, d.height);       c.setBounds(r);     }   } }