Java/Swing JFC/Customized Layout

Материал из Java эксперт
Перейти к: навигация, поиск

A layout manager that displays a single component in the center of its container.

   <source lang="java">
 

/*

* JCommon : a free general purpose class library for the Java(tm) platform
*
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
* 
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it 
* under the terms of the GNU Lesser General Public License as published by 
* the Free Software Foundation; either version 2.1 of the License, or 
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but 
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
* USA.  
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
* in the United States and other countries.]
* 
* -----------------
* CenterLayout.java
* -----------------
* (C) Copyright 2000-2005, by Object Refinery Limited.
*
* Original Author:  David Gilbert (for Object Refinery Limited);
* Contributor(s):   -;
*
* $Id: CenterLayout.java,v 1.6 2005/11/16 15:58:40 taqua Exp $
*
* Changes (from 5-Nov-2001)
* -------------------------
* 05-Nov-2001 : Changed package to com.jrefinery.layout.* (DG);
* 10-Oct-2002 : Fixed errors reported by Checkstyle (DG);
*
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import java.io.Serializable; /**

* A layout manager that displays a single component in the center of its
* container.
* 
* @author David Gilbert
*/

public class CenterLayout implements LayoutManager, Serializable {

 /** For serialization. */
 private static final long serialVersionUID = 469319532333015042L;
 /**
  * Creates a new layout manager.
  */
 public CenterLayout() {
 }
 /**
  * Returns the preferred size.
  * 
  * @param parent
  *          the parent.
  * 
  * @return the preferred size.
  */
 public Dimension preferredLayoutSize(final Container parent) {
   synchronized (parent.getTreeLock()) {
     final Insets insets = parent.getInsets();
     if (parent.getComponentCount() > 0) {
       final Component component = parent.getComponent(0);
       final Dimension d = component.getPreferredSize();
       return new Dimension((int) d.getWidth() + insets.left + insets.right, (int) d.getHeight()
           + insets.top + insets.bottom);
     } else {
       return new Dimension(insets.left + insets.right, insets.top + insets.bottom);
     }
   }
 }
 /**
  * Returns the minimum size.
  * 
  * @param parent
  *          the parent.
  * 
  * @return the minimum size.
  */
 public Dimension minimumLayoutSize(final Container parent) {
   synchronized (parent.getTreeLock()) {
     final Insets insets = parent.getInsets();
     if (parent.getComponentCount() > 0) {
       final Component component = parent.getComponent(0);
       final Dimension d = component.getMinimumSize();
       return new Dimension(d.width + insets.left + insets.right, d.height + insets.top
           + insets.bottom);
     } else {
       return new Dimension(insets.left + insets.right, insets.top + insets.bottom);
     }
   }
 }
 /**
  * Lays out the components.
  * 
  * @param parent
  *          the parent.
  */
 public void layoutContainer(final Container parent) {
   synchronized (parent.getTreeLock()) {
     if (parent.getComponentCount() > 0) {
       final Insets insets = parent.getInsets();
       final Dimension parentSize = parent.getSize();
       final Component component = parent.getComponent(0);
       final Dimension componentSize = component.getPreferredSize();
       final int xx = insets.left
           + (Math.max((parentSize.width - insets.left - insets.right - componentSize.width) / 2,
               0));
       final int yy = insets.top
           + (Math.max(
               (parentSize.height - insets.top - insets.bottom - componentSize.height) / 2, 0));
       component.setBounds(xx, yy, componentSize.width, componentSize.height);
     }
   }
 }
 /**
  * Not used.
  * 
  * @param comp
  *          the component.
  */
 public void addLayoutComponent(final Component comp) {
   // not used.
 }
 /**
  * Not used.
  * 
  * @param comp
  *          the component.
  */
 public void removeLayoutComponent(final Component comp) {
   // not used
 }
 /**
  * Not used.
  * 
  * @param name
  *          the component name.
  * @param comp
  *          the component.
  */
 public void addLayoutComponent(final String name, final Component comp) {
   // not used
 }
 /**
  * Not used.
  * 
  * @param name
  *          the component name.
  * @param comp
  *          the component.
  */
 public void removeLayoutComponent(final String name, final Component comp) {
   // not used
 }

}


 </source>
   
  
 
  



A layout manager that spaces components over six columns in seven different formats.

   <source lang="java">
 

/*

* JCommon : a free general purpose class library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
* 
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it 
* under the terms of the GNU Lesser General Public License as published by 
* the Free Software Foundation; either version 2.1 of the License, or 
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but 
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
* USA.  
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
* in the United States and other countries.]
* 
* -----------------
* FormatLayout.java
* -----------------
* (C) Copyright 2000-2005, by Object Refinery Limited.
*
* Original Author:  David Gilbert (for Object Refinery Limited);
* Contributor(s):   -;
*
* $Id: FormatLayout.java,v 1.4 2005/10/18 13:16:50 mungady Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.layout.* (DG);
* 26-Jun-2002 : Removed redundant code (DG);
* 10-Oct-2002 : Fixed errors reported by Checkstyle (DG);
*
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import java.io.Serializable; /**

* A layout manager that spaces components over six columns in seven different 
* formats.
*
* @author David Gilbert
*/

public class FormatLayout implements LayoutManager, Serializable {

   /** For serialization. */
   private static final long serialVersionUID = 2866692886323930722L;
   
   /** A useful constant representing layout format 1. */
   public static final int C = 1;
   /** A useful constant representing layout format 2. */
   public static final int LC = 2;
   /** A useful constant representing layout format 3. */
   public static final int LCB = 3;
   /** A useful constant representing layout format 4. */
   public static final int LCLC = 4;
   /** A useful constant representing layout format 5. */
   public static final int LCLCB = 5;
   /** A useful constant representing layout format 6. */
   public static final int LCBLC = 6;
   /** A useful constant representing layout format 7. */
   public static final int LCBLCB = 7;
   /** The layout format for each row. */
   private int[] rowFormats;
   /** The gap between the rows. */
   private int rowGap;
   /** 
    * The gaps between the columns (gap[0] is the gap following column zero). 
    */
   private int[] columnGaps;
   /** Working array for recording the height of each row. */
   private int[] rowHeights;
   /** The total height of the layout. */
   private int totalHeight;
   /** Working array for recording the width of each column. */
   private int[] columnWidths;
   /** The total width of the layout. */
   private int totalWidth;
   /** Combined width of columns 1 and 2. */
   private int columns1and2Width;
   /** Combined width of columns 4 and 5. */
   private int columns4and5Width;
   /** Combined width of columns 1 to 4. */
   private int columns1to4Width;
   /** Combined width of columns 1 to 5. */
   private int columns1to5Width;
   /** Combined width of columns 0 to 5. */
   private int columns0to5Width;
   /**
    * Constructs a new layout manager that can be used to create input forms.  
    * The layout manager works by arranging components in rows using six 
    * columns (some components will use more than one column).
*

* Any component can be added, but I think of them in terms of Labels, * Components, and Buttons. * The formats available are: C, LC, LCB, LCLC, LCLCB, LCBLC or LCBLCB. *

* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
C1 component in this row (spread across all six columns).
LC2 components, a label in the 1st column, and a component using the * remaining 5 columns).
LCB3 components, a label in the 1st column, a component spread across * the next 4, and a button in the last column.
LCLC4 components, a label in column 1, a component in 2-3, a label in * 4 and a component in 5-6.
LCLCB5 components, a label in column 1, a component in 2-3, a label * in 4, a component in 5 and a button in 6.
LCBLC5 components, a label in column 1, a component in 2, a button in 3, * a label in 4, a component in 5-6.
LCBLCB6 components, one in each column.
    * <P>
    * Columns 1 and 4 expand to accommodate the widest label, and 3 and 6 to
    * accommodate the widest button.
    * <P>
    * Each row will contain the number of components indicated by the format.  
    * Be sure to specify enough row formats to cover all the components you 
    * add to the layout.
    *
    * @param rowCount  the number of rows.
    * @param rowFormats  the row formats.
    */
   public FormatLayout(final int rowCount, final int[] rowFormats) {
       this.rowFormats = rowFormats;
       this.rowGap = 2;
       this.columnGaps = new int[5];
       this.columnGaps[0] = 10;
       this.columnGaps[1] = 5;
       this.columnGaps[2] = 5;
       this.columnGaps[3] = 10;
       this.columnGaps[4] = 5;
       // working structures...
       this.rowHeights = new int[rowCount];
       this.columnWidths = new int[6];
   }
   /**
    * Returns the preferred size of the component using this layout manager.
    *
    * @param parent  the parent.
    *
    * @return the preferred size of the component.
    */
   public Dimension preferredLayoutSize(final Container parent) {
       Component c0, c1, c2, c3, c4, c5;
       synchronized (parent.getTreeLock()) {
           final Insets insets = parent.getInsets();
           int componentIndex = 0;
           final int rowCount = this.rowHeights.length;
           for (int i = 0; i < this.columnWidths.length; i++) {
               this.columnWidths[i] = 0;
           }
           this.columns1and2Width = 0;
           this.columns4and5Width = 0;
           this.columns1to4Width = 0;
           this.columns1to5Width = 0;
           this.columns0to5Width = 0;
           this.totalHeight = 0;
           for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
           final int format 
               = this.rowFormats[rowIndex % this.rowFormats.length];
               switch (format) {
                   case FormatLayout.C:
                       c0 = parent.getComponent(componentIndex);
                       updateC(rowIndex, c0.getPreferredSize());
                       componentIndex = componentIndex + 1;
                       break;
                   case FormatLayout.LC:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       updateLC(rowIndex, c0.getPreferredSize(), 
                               c1.getPreferredSize());
                       componentIndex = componentIndex + 2;
                       break;
                   case FormatLayout.LCB:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       updateLCB(rowIndex,
                                 c0.getPreferredSize(),
                                 c1.getPreferredSize(),
                                 c2.getPreferredSize());
                       componentIndex = componentIndex + 3;
                       break;
                   case FormatLayout.LCLC:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       updateLCLC(rowIndex,
                                  c0.getPreferredSize(),
                                  c1.getPreferredSize(),
                                  c2.getPreferredSize(),
                                  c3.getPreferredSize());
                       componentIndex = componentIndex + 4;
                       break;
                   case FormatLayout.LCBLC:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       c4 = parent.getComponent(componentIndex + 4);
                       updateLCBLC(rowIndex,
                                   c0.getPreferredSize(),
                                   c1.getPreferredSize(),
                                   c2.getPreferredSize(),
                                   c3.getPreferredSize(),
                                   c4.getPreferredSize());
                       componentIndex = componentIndex + 5;
                       break;
                   case FormatLayout.LCLCB:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       c4 = parent.getComponent(componentIndex + 4);
                       updateLCLCB(rowIndex,
                                   c0.getPreferredSize(),
                                   c1.getPreferredSize(),
                                   c2.getPreferredSize(),
                                   c3.getPreferredSize(),
                                   c4.getPreferredSize());
                       componentIndex = componentIndex + 5;
                       break;
                   case FormatLayout.LCBLCB:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       c4 = parent.getComponent(componentIndex + 4);
                       c5 = parent.getComponent(componentIndex + 5);
                       updateLCBLCB(rowIndex,
                                    c0.getPreferredSize(),
                                    c1.getPreferredSize(),
                                    c2.getPreferredSize(),
                                    c3.getPreferredSize(),
                                    c4.getPreferredSize(),
                                    c5.getPreferredSize());
                       componentIndex = componentIndex + 6;
                       break;
               }
           }
           complete();
           return new Dimension(this.totalWidth + insets.left + insets.right,
                   this.totalHeight + (rowCount - 1) * this.rowGap
                                + insets.top + insets.bottom);
       }
   }
   /**
    * Returns the minimum size of the component using this layout manager.
    *
    * @param parent  the parent.
    *
    * @return the minimum size of the component
    */
   public Dimension minimumLayoutSize(final Container parent) {
       Component c0, c1, c2, c3, c4, c5;
       synchronized (parent.getTreeLock()) {
           final Insets insets = parent.getInsets();
           int componentIndex = 0;
           final int rowCount = this.rowHeights.length;
           for (int i = 0; i < this.columnWidths.length; i++) {
               this.columnWidths[i] = 0;
           }
           this.columns1and2Width = 0;
           this.columns4and5Width = 0;
           this.columns1to4Width = 0;
           this.columns1to5Width = 0;
           this.columns0to5Width = 0;
           final int totalHeight = 0;
           for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
               final int format 
                   = this.rowFormats[rowIndex % this.rowFormats.length];
               switch (format) {
                   case FormatLayout.C:
                       c0 = parent.getComponent(componentIndex);
                       this.columns0to5Width = Math.max(
                           this.columns0to5Width, c0.getMinimumSize().width
                       );
                       componentIndex = componentIndex + 1;
                       break;
                   case FormatLayout.LC:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       updateLC(rowIndex,
                                c0.getMinimumSize(),
                                c1.getMinimumSize());
                       componentIndex = componentIndex + 2;
                       break;
                   case FormatLayout.LCB:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       updateLCB(rowIndex,
                                 c0.getMinimumSize(),
                                 c1.getMinimumSize(),
                                 c2.getMinimumSize());
                       componentIndex = componentIndex + 3;
                       break;
                   case FormatLayout.LCLC:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       updateLCLC(rowIndex,
                                  c0.getMinimumSize(),
                                  c1.getMinimumSize(),
                                  c2.getMinimumSize(),
                                  c3.getMinimumSize());
                       componentIndex = componentIndex + 3;
                       break;
                   case FormatLayout.LCBLC:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       c4 = parent.getComponent(componentIndex + 4);
                       updateLCBLC(rowIndex,
                                   c0.getMinimumSize(),
                                   c1.getMinimumSize(),
                                   c2.getMinimumSize(),
                                   c3.getMinimumSize(),
                                   c4.getMinimumSize());
                       componentIndex = componentIndex + 4;
                       break;
                   case FormatLayout.LCLCB:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       c4 = parent.getComponent(componentIndex + 4);
                       updateLCLCB(rowIndex,
                                   c0.getMinimumSize(),
                                   c1.getMinimumSize(),
                                   c2.getMinimumSize(),
                                   c3.getMinimumSize(),
                                   c4.getMinimumSize());
                       componentIndex = componentIndex + 4;
                       break;
                   case FormatLayout.LCBLCB:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       c4 = parent.getComponent(componentIndex + 4);
                       c5 = parent.getComponent(componentIndex + 5);
                       updateLCBLCB(rowIndex,
                                    c0.getMinimumSize(),
                                    c1.getMinimumSize(),
                                    c2.getMinimumSize(),
                                    c3.getMinimumSize(),
                                    c4.getMinimumSize(),
                                    c5.getMinimumSize());
                       componentIndex = componentIndex + 5;
                       break;
               }
           }
           complete();
           return new Dimension(this.totalWidth + insets.left + insets.right,
                                totalHeight + (rowCount - 1) * this.rowGap
                                + insets.top + insets.bottom);
       }
   }
   /**
    * Performs the layout of the container.
    *
    * @param parent  the parent.
    */
   public void layoutContainer(final Container parent) {
       Component c0, c1, c2, c3, c4, c5;
       synchronized (parent.getTreeLock()) {
           final Insets insets = parent.getInsets();
           int componentIndex = 0;
           final int rowCount = this.rowHeights.length;
           for (int i = 0; i < this.columnWidths.length; i++) {
               this.columnWidths[i] = 0;
           }
           this.columns1and2Width = 0;
           this.columns4and5Width = 0;
           this.columns1to4Width = 0;
           this.columns1to5Width = 0;
           this.columns0to5Width 
               = parent.getBounds().width - insets.left - insets.right;
           this.totalHeight = 0;
           for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
               final int format 
                   = this.rowFormats[rowIndex % this.rowFormats.length];
               switch (format) {
                   case FormatLayout.C:
                       c0 = parent.getComponent(componentIndex);
                       updateC(rowIndex, c0.getPreferredSize());
                       componentIndex = componentIndex + 1;
                       break;
                   case FormatLayout.LC:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       updateLC(rowIndex, c0.getPreferredSize(), 
                               c1.getPreferredSize());
                       componentIndex = componentIndex + 2;
                       break;
                   case FormatLayout.LCB:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       updateLCB(rowIndex,
                                 c0.getPreferredSize(),
                                 c1.getPreferredSize(),
                                 c2.getPreferredSize());
                       componentIndex = componentIndex + 3;
                       break;
                   case FormatLayout.LCLC:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       updateLCLC(rowIndex,
                                  c0.getPreferredSize(),
                                  c1.getPreferredSize(),
                                  c2.getPreferredSize(),
                                  c3.getPreferredSize());
                       componentIndex = componentIndex + 4;
                       break;
                   case FormatLayout.LCBLC:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       c4 = parent.getComponent(componentIndex + 4);
                       updateLCBLC(rowIndex,
                                   c0.getPreferredSize(),
                                   c1.getPreferredSize(),
                                   c2.getPreferredSize(),
                                   c3.getPreferredSize(),
                                   c4.getPreferredSize());
                       componentIndex = componentIndex + 5;
                       break;
                   case FormatLayout.LCLCB:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       c4 = parent.getComponent(componentIndex + 4);
                       updateLCLCB(rowIndex,
                                   c0.getPreferredSize(),
                                   c1.getPreferredSize(),
                                   c2.getPreferredSize(),
                                   c3.getPreferredSize(),
                                   c4.getPreferredSize());
                       componentIndex = componentIndex + 5;
                       break;
                   case FormatLayout.LCBLCB:
                       c0 = parent.getComponent(componentIndex);
                       c1 = parent.getComponent(componentIndex + 1);
                       c2 = parent.getComponent(componentIndex + 2);
                       c3 = parent.getComponent(componentIndex + 3);
                       c4 = parent.getComponent(componentIndex + 4);
                       c5 = parent.getComponent(componentIndex + 5);
                       updateLCBLCB(rowIndex,
                                    c0.getPreferredSize(),
                                    c1.getPreferredSize(),
                                    c2.getPreferredSize(),
                                    c3.getPreferredSize(),
                                    c4.getPreferredSize(),
                                    c5.getPreferredSize());
                       componentIndex = componentIndex + 6;
                       break;
               }
           }
           complete();
           componentIndex = 0;
           int rowY = insets.top;
           final int[] rowX = new int[6];
           rowX[0] = insets.left;
           rowX[1] = rowX[0] + this.columnWidths[0] + this.columnGaps[0];
           rowX[2] = rowX[1] + this.columnWidths[1] + this.columnGaps[1];
           rowX[3] = rowX[2] + this.columnWidths[2] + this.columnGaps[2];
           rowX[4] = rowX[3] + this.columnWidths[3] + this.columnGaps[3];
           rowX[5] = rowX[4] + this.columnWidths[4] + this.columnGaps[4];
           final int w1to2 = this.columnWidths[1] + this.columnGaps[1] 
                             + this.columnWidths[2];
           final int w4to5 = this.columnWidths[4] + this.columnGaps[4] 
                             + this.columnWidths[5];
           final int w1to4 = w1to2 + this.columnGaps[2] + this.columnWidths[3]
                       + this.columnGaps[3] + this.columnWidths[4];
           final int w1to5 = w1to4 + this.columnGaps[4] + this.columnWidths[5];
           final int w0to5 = w1to5 + this.columnWidths[0] + this.columnGaps[0];
           for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
               final int format 
                   = this.rowFormats[rowIndex % this.rowFormats.length];
               switch (format) {
               case FormatLayout.C:
                   c0 = parent.getComponent(componentIndex);
                   c0.setBounds(rowX[0], rowY, w0to5, 
                           c0.getPreferredSize().height);
                   componentIndex = componentIndex + 1;
                   break;
               case FormatLayout.LC:
                   c0 = parent.getComponent(componentIndex);
                   c0.setBounds(
                       rowX[0],
                       rowY + (this.rowHeights[rowIndex] 
                                    - c0.getPreferredSize().height) / 2,
                       this.columnWidths[0], c0.getPreferredSize().height
                   );
                   c1 = parent.getComponent(componentIndex + 1);
                   c1.setBounds(
                       rowX[1],
                       rowY + (this.rowHeights[rowIndex] 
                                    - c1.getPreferredSize().height) / 2,
                       w1to5, c1.getPreferredSize().height
                   );
                   componentIndex = componentIndex + 2;
                   break;
               case FormatLayout.LCB:
                   c0 = parent.getComponent(componentIndex);
                   c0.setBounds(
                       rowX[0],
                       rowY + (this.rowHeights[rowIndex] 
                                    - c0.getPreferredSize().height) / 2,
                       this.columnWidths[0], c0.getPreferredSize().height
                   );
                   c1 = parent.getComponent(componentIndex + 1);
                   c1.setBounds(
                       rowX[1],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c1.getPreferredSize().height) / 2,
                       w1to4, c1.getPreferredSize().height
                   );
                   c2 = parent.getComponent(componentIndex + 2);
                   c2.setBounds(
                       rowX[5],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c2.getPreferredSize().height) / 2,
                       this.columnWidths[5], c2.getPreferredSize().height
                   );
                   componentIndex = componentIndex + 3;
                   break;
               case FormatLayout.LCLC:
                   c0 = parent.getComponent(componentIndex);
                   c0.setBounds(
                       rowX[0],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c0.getPreferredSize().height) / 2,
                       this.columnWidths[0], c0.getPreferredSize().height
                   );
                   c1 = parent.getComponent(componentIndex + 1);
                   c1.setBounds(
                       rowX[1],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c1.getPreferredSize().height) / 2,
                       w1to2, c1.getPreferredSize().height
                   );
                   c2 = parent.getComponent(componentIndex + 2);
                   c2.setBounds(
                       rowX[3],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c2.getPreferredSize().height) / 2,
                       this.columnWidths[3], c2.getPreferredSize().height
                   );
                   c3 = parent.getComponent(componentIndex + 3);
                   c3.setBounds(
                       rowX[4],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c3.getPreferredSize().height) / 2,
                       w4to5, c3.getPreferredSize().height
                   );
                   componentIndex = componentIndex + 4;
                   break;
               case FormatLayout.LCBLC:
                   c0 = parent.getComponent(componentIndex);
                   c0.setBounds(
                       rowX[0],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c0.getPreferredSize().height) / 2,
                       this.columnWidths[0], c0.getPreferredSize().height
                   );
                   c1 = parent.getComponent(componentIndex + 1);
                   c1.setBounds(
                       rowX[1],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c1.getPreferredSize().height) / 2,
                       this.columnWidths[1], c1.getPreferredSize().height
                   );
                   c2 = parent.getComponent(componentIndex + 2);
                   c2.setBounds(
                       rowX[2],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c2.getPreferredSize().height) / 2,
                       this.columnWidths[2], c2.getPreferredSize().height
                   );
                   c3 = parent.getComponent(componentIndex + 3);
                   c3.setBounds(
                       rowX[3],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c3.getPreferredSize().height) / 2,
                       this.columnWidths[3], c3.getPreferredSize().height
                   );
                   c4 = parent.getComponent(componentIndex + 4);
                   c4.setBounds(
                       rowX[4],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c4.getPreferredSize().height) / 2,
                       w4to5, c4.getPreferredSize().height
                   );
                   componentIndex = componentIndex + 5;
                   break;
               case FormatLayout.LCLCB:
                   c0 = parent.getComponent(componentIndex);
                   c0.setBounds(
                       rowX[0],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c0.getPreferredSize().height) / 2,
                       this.columnWidths[0], c0.getPreferredSize().height
                   );
                   c1 = parent.getComponent(componentIndex + 1);
                   c1.setBounds(
                       rowX[1],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c1.getPreferredSize().height) / 2,
                       w1to2, c1.getPreferredSize().height
                   );
                   c2 = parent.getComponent(componentIndex + 2);
                   c2.setBounds(
                       rowX[3],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c2.getPreferredSize().height) / 2,
                       this.columnWidths[3], c2.getPreferredSize().height
                   );
                   c3 = parent.getComponent(componentIndex + 3);
                   c3.setBounds(
                       rowX[4],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c3.getPreferredSize().height) / 2,
                       this.columnWidths[4], c3.getPreferredSize().height
                   );
                   c4 = parent.getComponent(componentIndex + 4);
                   c4.setBounds(
                       rowX[5],
                       rowY + (this.rowHeights[rowIndex] 
                                   - c4.getPreferredSize().height) / 2,
                       this.columnWidths[5], c4.getPreferredSize().height
                   );
                   componentIndex = componentIndex + 5;
                   break;
               case FormatLayout.LCBLCB:
                   c0 = parent.getComponent(componentIndex);
                   c0.setBounds(
                       rowX[0],
                       rowY + (this.rowHeights[rowIndex] 
                                    - c0.getPreferredSize().height) / 2,
                       this.columnWidths[0], c0.getPreferredSize().height
                   );
                   c1 = parent.getComponent(componentIndex + 1);
                   c1.setBounds(
                       rowX[1],
                       rowY + (this.rowHeights[rowIndex] 
                                    - c1.getPreferredSize().height) / 2,
                       this.columnWidths[1], c1.getPreferredSize().height
                   );
                   c2 = parent.getComponent(componentIndex + 2);
                   c2.setBounds(
                       rowX[2],
                       rowY + (this.rowHeights[rowIndex] 
                                    - c2.getPreferredSize().height) / 2,
                       this.columnWidths[2], c2.getPreferredSize().height
                   );
                   c3 = parent.getComponent(componentIndex + 3);
                   c3.setBounds(
                       rowX[3],
                       rowY + (this.rowHeights[rowIndex] 
                                    - c3.getPreferredSize().height) / 2,
                       this.columnWidths[3], c3.getPreferredSize().height
                   );
                   c4 = parent.getComponent(componentIndex + 4);
                   c4.setBounds(
                       rowX[4],
                       rowY + (this.rowHeights[rowIndex] 
                                    - c4.getPreferredSize().height) / 2,
                       this.columnWidths[4], c4.getPreferredSize().height
                   );
                   c5 = parent.getComponent(componentIndex + 5);
                   c5.setBounds(
                       rowX[5],
                       rowY + (this.rowHeights[rowIndex] 
                                    - c5.getPreferredSize().height) / 2,
                       this.columnWidths[5], c5.getPreferredSize().height
                   );
                   componentIndex = componentIndex + 6;
                   break;
                   }
               rowY = rowY + this.rowHeights[rowIndex] + this.rowGap;
           }
       }
   }
   /**
    * Processes a row in "C" format.
    *
    * @param rowIndex  the row index.
    * @param d0  dimension 0.
    */
   protected void updateC(final int rowIndex, final Dimension d0) {
       this.rowHeights[rowIndex] = d0.height;
       this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
       this.columns0to5Width = Math.max(this.columns0to5Width, d0.width);
   }
   /**
    * Processes a row in "LC" format.
    *
    * @param rowIndex  the row index.
    * @param d0  dimension 0.
    * @param d1  dimension 1.
    */
   protected void updateLC(final int rowIndex, final Dimension d0, 
                           final Dimension d1) {
       this.rowHeights[rowIndex] = Math.max(d0.height, d1.height);
       this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
       this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
       this.columns1to5Width = Math.max(this.columns1to5Width, d1.width);
   }
   /**
    * Processes a row in "LCB" format.
    *
    * @param rowIndex  the row index.
    * @param d0  dimension 0.
    * @param d1  dimension 1.
    * @param d2  dimension 2.
    */
   protected void updateLCB(final int rowIndex,
                            final Dimension d0, final Dimension d1, 
                            final Dimension d2) {
       this.rowHeights[rowIndex] 
              = Math.max(d0.height, Math.max(d1.height, d2.height));
       this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
       this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
       this.columns1to4Width = Math.max(this.columns1to4Width, d1.width);
       this.columnWidths[5] = Math.max(this.columnWidths[5], d2.width);
   }
   /**
    * Processes a row in "LCLC" format.
    *
    * @param rowIndex  the row index.
    * @param d0  dimension 0.
    * @param d1  dimension 1.
    * @param d2  dimension 2.
    * @param d3  dimension 3.
    */
   protected void updateLCLC(final int rowIndex, final Dimension d0, 
                             final Dimension d1, final Dimension d2, 
                             final Dimension d3) {
       this.rowHeights[rowIndex] = Math.max(Math.max(d0.height, d1.height),
                                       Math.max(d2.height, d3.height));
       this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
       this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
       this.columns1and2Width = Math.max(this.columns1and2Width, d1.width);
       this.columnWidths[3] = Math.max(this.columnWidths[3], d2.width);
       this.columns4and5Width = Math.max(this.columns4and5Width, d3.width);
   }
   /**
    * Processes a row in "LCBLC" format.
    *
    * @param rowIndex  the row index.
    * @param d0  dimension 0.
    * @param d1  dimension 1.
    * @param d2  dimension 2.
    * @param d3  dimension 3.
    * @param d4  dimension 4.
    */
   protected void updateLCBLC(final int rowIndex, final Dimension d0, 
                              final Dimension d1, final Dimension d2, 
                              final Dimension d3, final Dimension d4) {
       this.rowHeights[rowIndex] = (Math.max(
           d0.height,
           Math.max(Math.max(d1.height, d2.height),
           Math.max(d3.height, d4.height)))
       );
       this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
       this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
       this.columnWidths[1] = Math.max(this.columnWidths[1], d1.width);
       this.columnWidths[2] = Math.max(this.columnWidths[2], d2.width);
       this.columnWidths[3] = Math.max(this.columnWidths[3], d3.width);
       this.columns4and5Width = Math.max(this.columns4and5Width, d4.width);
   }
   /**
    * Processes a row in "LCLCB" format.
    *
    * @param rowIndex  the row index.
    * @param d0  dimension 0.
    * @param d1  dimension 1.
    * @param d2  dimension 2.
    * @param d3  dimension 3.
    * @param d4  dimension 4.
    */
   protected void updateLCLCB(final int rowIndex, final Dimension d0, 
                              final Dimension d1, final Dimension d2,
                              final Dimension d3, final Dimension d4) {
       this.rowHeights[rowIndex] = (Math.max(d0.height,
                                    Math.max(Math.max(d1.height, d2.height),
                                             Math.max(d3.height, d4.height))));
       this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
       this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
       this.columns1and2Width = Math.max(this.columns1and2Width, d1.width);
       this.columnWidths[3] = Math.max(this.columnWidths[3], d2.width);
       this.columnWidths[4] = Math.max(this.columnWidths[4], d3.width);
       this.columnWidths[5] = Math.max(this.columnWidths[5], d4.width);
   }
   /**
    * Processes a row in "LCBLCB" format.
    *
    * @param rowIndex  the row index.
    * @param d0  dimension 0.
    * @param d1  dimension 1.
    * @param d2  dimension 2.
    * @param d3  dimension 3.
    * @param d4  dimension 4.
    * @param d5  dimension 5.
    */
   protected void updateLCBLCB(final int rowIndex,
                               final Dimension d0, final Dimension d1, 
                               final Dimension d2,
                               final Dimension d3, final Dimension d4, 
                               final Dimension d5) {
       this.rowHeights[rowIndex] = Math.max(
           Math.max(d0.height, d1.height),
           Math.max(Math.max(d2.height, d3.height),
                    Math.max(d4.height, d5.height))
       );
       this.totalHeight = this.totalHeight + this.rowHeights[rowIndex];
       this.columnWidths[0] = Math.max(this.columnWidths[0], d0.width);
       this.columnWidths[1] = Math.max(this.columnWidths[1], d1.width);
       this.columnWidths[2] = Math.max(this.columnWidths[2], d2.width);
       this.columnWidths[3] = Math.max(this.columnWidths[3], d3.width);
       this.columnWidths[4] = Math.max(this.columnWidths[4], d4.width);
       this.columnWidths[5] = Math.max(this.columnWidths[5], d5.width);
   }
   /**
    * Finishes of the processing.
    */
   public void complete() {
       this.columnWidths[1] = Math.max(
            this.columnWidths[1],
            this.columns1and2Width - this.columnGaps[1] - this.columnWidths[2]
       );
       this.columnWidths[4] = Math.max(
           this.columnWidths[4],
           Math.max(
               this.columns4and5Width - this.columnGaps[4] 
               - this.columnWidths[5],
               Math.max(
                   this.columns1to4Width - this.columnGaps[1] 
                       - this.columnGaps[2] - this.columnGaps[3] 
                       - this.columnWidths[1] - this.columnWidths[2] 
                       - this.columnWidths[3],
                   this.columns1to5Width - this.columnGaps[1] 
                       - this.columnGaps[2] - this.columnGaps[3] 
                       - this.columnWidths[1] - this.columnWidths[2] 
                       - this.columnWidths[3] - this.columnGaps[4]
               )
           )
       );
       int leftWidth = this.columnWidths[0] + this.columnGaps[0]
                     + this.columnWidths[1] + this.columnGaps[1] 
                     + this.columnWidths[2];
       int rightWidth = this.columnWidths[3] + this.columnGaps[3]
                      + this.columnWidths[4] + this.columnGaps[4] 
                      + this.columnWidths[5];
       if (splitLayout()) {
           if (leftWidth > rightWidth) {
               final int mismatch = leftWidth - rightWidth;
               this.columnWidths[4] = this.columnWidths[4] + mismatch;
               rightWidth = rightWidth + mismatch;
           }
           else {
               final int mismatch = rightWidth - leftWidth;
               this.columnWidths[1] = this.columnWidths[1] + mismatch;
               leftWidth = leftWidth + mismatch;
           }
       }
       this.totalWidth = leftWidth + this.columnGaps[2] + rightWidth;
       if (this.columns0to5Width > this.totalWidth) {
           final int spaceToAdd = (this.columns0to5Width - this.totalWidth);
           if (splitLayout()) {
               final int halfSpaceToAdd = spaceToAdd / 2;
               this.columnWidths[1] = this.columnWidths[1] + halfSpaceToAdd;
               this.columnWidths[4] = this.columnWidths[4] + spaceToAdd 
                   - halfSpaceToAdd;
               this.totalWidth = this.totalWidth + spaceToAdd;
           }
           else {
               this.columnWidths[1] = this.columnWidths[1] + spaceToAdd;
               this.totalWidth = this.totalWidth + spaceToAdd;
           }
       }
   }
   /**
    * Returns true if this layout involves a split into two sections.
    *
    * @return true if this layout involves a split into two 
    *         sections.
    */
   private boolean splitLayout() {
       for (int i = 0; i < this.rowFormats.length; i++) {
           if (this.rowFormats[i] > FormatLayout.LCB) {
               return true;
           }
       }
       return false;
   }
   /**
    * Not used.
    *
    * @param comp  the component.
    */
   public void addLayoutComponent(final Component comp) {
       // not used
   }
   /**
    * Not used.
    *
    * @param comp  the component.
    */
   public void removeLayoutComponent(final Component comp) {
       // not used
   }
   /**
    * Not used.
    *
    * @param name  the component name.
    * @param comp  the component.
    */
   public void addLayoutComponent(final String name, final Component comp) {
       // not used
   }
   /**
    * Not used.
    *
    * @param name  the component name.
    * @param comp  the component.
    */
   public void removeLayoutComponent(final String name, final Component comp) {
       // not used
   }

}


 </source>
   
  
 
  



Applet GUI demo of TreeLayout layout manager

   <source lang="java">
   

import java.applet.Applet; import java.awt.Button; import java.awt.Canvas; import java.awt.Color; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.Label; import java.awt.LayoutManager; import java.awt.List; import java.awt.Rectangle; import java.awt.TextField; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; /**

* Applet GUI demo of Gamelan TreeLayout layout manager. Constructs a tree and,
* for each entry, makes a button that jumps to it.
* 
* The input language is a file like this: R Java Resources # root L - Resources
* at Sun # label B http://www.sun.ru/foo/bar Interesting Stuff # URLbutton B
* http://javasoft.ru/b/c More Stuff # URLbutton
* 
* The result is (supposedly) a beautiful(?) tree. Each L is a top-level label,
* and each B is in the tree below it.
* 
* Could be made much fancier with getParameter("FontName"), "FontSize",
* adjusting width with fontMetrics, etc. Works adequately for now.
*/

public class TreeLinkTest extends Applet {

 TreeLayout tl;
 public void init() {
   tl = new TreeLayout();
   setLayout(tl);
   Button root = new Button("This is the root");
   add("Root", root);
   tl.setRoot(root);
   Component x = new Label("A random label");
   add("label", x);
   tl.setParent(x, root);
   Component y;
   y = new TextField("Add any component");
   add("comp", y);
   tl.setParent(y, root);
   x = new List();
   ((List) x).add("List entry");
   ((List) x).add("Similarly useless list entry");
   add("list", x);
   tl.setParent(x, root);
   x = new Button("Extremely long and unnecessary button title");
   add("button", x);
   tl.setParent(x, y);
   x = new MyCanvas(getImage(getDocumentBase(), "icons/tools.gif"));
   add("image", x);
   tl.setParent(x, y);
 }
 public void paint(Graphics g) {
   super.paint(g);
   tl.paintLines(g, getBackground());
 }
 class MyCanvas extends Canvas {
   Image img;
   MyCanvas(Image img) {
     this.img = img;
   }
   public Dimension getPreferredSize() {
     return new Dimension(64, 64);
   }
   public void update(Graphics g) {
     paint(g);
   }
   public void paint(Graphics g) {
     g.drawImage(img, 0, getSize().height / 2 - 16, 32, 32, this);
   }
 }

} /**

* Simple layout manager that arranges its children in a tree. The tree always
* expands to fill the available area, and the internal components are resized
* to fit the area proportional to their preferred size and the actual available
* size.
* 
* This layout manager requires several method calls beyond the normal layout
* manager. Please notice the following: * Components must be added using the
* add(String, Component) method. The strings don"t have to be unique, but must
* be present. * Each instance must have exactly one root object, which must be
* add()ed, then  setRoot()ed. * Each component after the root must first
* be added and then must be connected into the tree using setParent(child,
* parent). * If you want lines between parents and children, you must
*  call paintLines() from your applet"s paint() method.
* 
* @author name unknown, xxx@blackdown.org
*/

class TreeLayout implements LayoutManager {

 TreeNode root;
 Hashtable nodes;
 public TreeLayout() {
   nodes = new Hashtable();
 }
 public void addLayoutComponent(String name, Component comp) {
   TreeNode tn = new TreeNode(comp);
   nodes.put(comp, tn);
 }
 public void removeLayoutComponent(Component comp) {
   nodes.remove(comp);
 }
 /**
  * You must make this call, otherwise none of the components will
  * be layed out.
  */
 public void setRoot(Component c) {
   root = (TreeNode) nodes.get(c);
 }
 /**
  * Sets the tree parent of a child. The components must have been
  * previously added. If either component has not previously been added, this
  * injunction is silently ignored. Cycles are not checked.
  */
 public void setParent(Component child, Component parent) {
   TreeNode p = (TreeNode) nodes.get(parent);
   TreeNode c = (TreeNode) nodes.get(child);
   if ((p != null) && (c != null))
     p.addChild(c);
 }
 public Dimension minimumLayoutSize(Container target) {
   Dimension d = root.getMinimumSize();
   Insets insets = target.getInsets();
   d.width += insets.left + insets.right;
   d.height += insets.top + insets.bottom;
   return d;
 }
 public Dimension preferredLayoutSize(Container target) {
   Dimension d = root.getPreferredSize();
   Insets insets = target.getInsets();
   d.width += insets.left + insets.right;
   d.height += insets.top + insets.bottom;
   return d;
 }
 public void layoutContainer(Container target) {
   Insets insets = target.getInsets();
   Dimension d = target.getSize();
   Dimension root_pref = root.getPreferredSize();
   double xscale = ((double) (d.width - insets.left - insets.right) / (double) (root_pref.width));
   double yscale = ((double) (d.height - insets.top - insets.bottom) / (double) (root_pref.height));
   root.doLayout(xscale, yscale, insets.left, insets.top);
 }
 /**
  * This piece of hackery is needed since one cant really draw things from a
  * layout manager. Call this if you want to draw lines between components.
  */
 public void paintLines(Graphics g, Color bg) {
   Color dk = bg.darker();
   Color br = bg.brighter();
   root.paintLines(g, dk, br);
 }

} class TreeNode {

 Component comp;
 Vector children;
 Dimension prefSz, minSz;
 TreeNode(Component comp) {
   super();
   this.rup = comp;
   children = new Vector();
 }
 Dimension getMinimumSize() {
   if (!comp.isVisible())
     return new Dimension(0, 0);
   if (minSz == null) {
     Dimension d = comp.getMinimumSize();
     minSz = new Dimension(d.width, d.height);
     if (children.size() > 0) {
       for (Enumeration e = children.elements(); e.hasMoreElements();) {
         TreeNode t = (TreeNode) (e.nextElement());
         if (t.rup.isVisible()) {
           d = t.getMinimumSize();
           minSz.height += d.height;
           minSz.width = Math.max(d.width, minSz.width);
         }
       }
     }
   }
   return minSz;
 }
 Dimension getPreferredSize() {
   if (!comp.isVisible())
     return new Dimension(0, 0);
   if (prefSz == null) {
     Dimension d = comp.getPreferredSize();
     prefSz = new Dimension(d.width, d.height);
     if (children.size() > 0) {
       int wmax = 0;
       for (Enumeration e = children.elements(); e.hasMoreElements();) {
         TreeNode t = (TreeNode) (e.nextElement());
         if (t.rup.isVisible()) {
           d = t.getPreferredSize();
           prefSz.height += d.height;
           if (wmax < d.width) {
             wmax = d.width;
           }
         }
       }
       prefSz.width += wmax;
     }
   }
   return prefSz;
 }
 void addChild(TreeNode t) {
   children.addElement(t);
   prefSz = null;
   minSz = null;
 }
 void removeChild(TreeNode t) {
   children.removeElement(t);
   prefSz = null;
   minSz = null;
 }
 void paintLines(Graphics g, Color dk, Color br) {
   if (comp.isVisible()) {
     Rectangle b = comp.getBounds();
     int x1off = b.x + b.width / 2;
     int x2off = b.x + b.width;
     int y1off = b.y;
     for (Enumeration e = children.elements(); e.hasMoreElements();) {
       TreeNode tn = (TreeNode) (e.nextElement());
       if (tn.rup.isVisible()) {
         Rectangle bn = tn.rup.getBounds();
         int y2off = bn.y + bn.height / 2;
         g.setColor(dk);
         g.drawLine(x1off, y1off, x1off, y2off);
         g.drawLine(x1off, y2off - 1, x2off, y2off - 1);
         g.setColor(br);
         g.drawLine(x1off + 1, y1off, x1off + 1, y2off);
         g.drawLine(x1off, y2off, x2off, y2off);
         tn.paintLines(g, dk, br);
       }
     }
   }
 }
 void doLayout(double xscale, double yscale, int x, int y) {
   // x and y are the offsets into the
   // Container where we start doing the
   // goodies for this Node
   if (comp.isVisible()) {
     Dimension pref = comp.getPreferredSize();
     int ht = (int) Math.round(yscale * pref.height);
     int wd = (int) Math.round(xscale * pref.width);
     ht = (pref.height < ht) ? pref.height : ht;
     wd = (pref.width < wd) ? pref.width : wd;
     comp.setBounds(x, y, wd, ht);
     y += ht;
     x += wd;
     for (Enumeration e = children.elements(); e.hasMoreElements();) {
       TreeNode tn = (TreeNode) (e.nextElement());
       if (tn.rup.isVisible()) {
         pref = tn.getPreferredSize();
         tn.doLayout(xscale, yscale, x, y);
         y += (int) Math.round(yscale * pref.height);
       }
     }
   }
 }

}



 </source>
   
  
 
  



A simple layoutmanager to overlay all components of a parent.

   <source lang="java">
 

/*

* JCommon : a free general purpose class library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
* 
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it 
* under the terms of the GNU Lesser General Public License as published by 
* the Free Software Foundation; either version 2.1 of the License, or 
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but 
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
* USA.  
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
* in the United States and other countries.]
*
* ------------------------------
* OverlayLayout.java
* ------------------------------
* (C)opyright 2003, by Thomas Morgner and Contributors.
*
* Original Author:  Thomas Morgner;
* Contributor(s):   -;
*
* $Id: OverlayLayout.java,v 1.5 2005/10/18 13:18:34 mungady Exp $
*
* Changes
* -------------------------
* 09-12-2003 : Initial version
*
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.Rectangle; /**

* A simple layoutmanager to overlay all components of a parent.
* <p/>
* This layout manager acts similiar to the card layout, but all
* childs of the parent band have the same size and all childs can
* be visible at the same time.
*
* @author Thomas Morgner
*/

public final class OverlayLayout implements LayoutManager {

   /**
    * A flag that defines, whether invisible components should be ignored when
    * computing the layout.
    */
   private boolean ignoreInvisible;
   /**
    * Creates a new instance.
    * 
    * @param ignoreInvisible  whether to ignore invisible components when computing the layout.
    */
   public OverlayLayout(final boolean ignoreInvisible) {
       this.ignoreInvisible = ignoreInvisible;
   }
   /**
    * DefaultConstructor.
    */
   public OverlayLayout() {
   }
   /**
    * If the layout manager uses a per-component string,
    * adds the component comp to the layout,
    * associating it
    * with the string specified by name.
    *
    * @param name the string to be associated with the component
    * @param comp the component to be added
    */
   public void addLayoutComponent(final String name, final Component comp) {
   }
   /**
    * Removes the specified component from the layout.
    *
    * @param comp the component to be removed
    */
   public void removeLayoutComponent(final Component comp) {
   }
   /**
    * Lays out the specified container.
    *
    * @param parent the container to be laid out
    */
   public void layoutContainer(final Container parent) {
       synchronized (parent.getTreeLock()) {
           final Insets ins = parent.getInsets();
           final Rectangle bounds = parent.getBounds();
           final int width = bounds.width - ins.left - ins.right;
           final int height = bounds.height - ins.top - ins.bottom;
           final Component[] comps = parent.getComponents();
           for (int i = 0; i < comps.length; i++) {
               final Component c = comps[i];
               if ((comps[i].isVisible() == false) && this.ignoreInvisible) {
                   continue;
               }
               c.setBounds(ins.left, ins.top, width, height);
           }
       }
   }
   /**
    * Calculates the minimum size dimensions for the specified
    * container, given the components it contains.
    *
    * @param parent the component to be laid out
    * @return the minimum size computed for the parent.
    * @see #preferredLayoutSize
    */
   public Dimension minimumLayoutSize(final Container parent) {
       synchronized (parent.getTreeLock()) {
           final Insets ins = parent.getInsets();
           final Component[] comps = parent.getComponents();
           int height = 0;
           int width = 0;
           for (int i = 0; i < comps.length; i++) {
               if ((comps[i].isVisible() == false) && this.ignoreInvisible) {
                   continue;
               }
               final Dimension pref = comps[i].getMinimumSize();
               if (pref.height > height) {
                   height = pref.height;
               }
               if (pref.width > width) {
                   width = pref.width;
               }
           }
           return new Dimension(width + ins.left + ins.right,
               height + ins.top + ins.bottom);
       }
   }
   /**
    * Calculates the preferred size dimensions for the specified
    * container, given the components it contains.
    *
    * @param parent the container to be laid out
    * @return the preferred size computed for the parent.
    * @see #minimumLayoutSize
    */
   public Dimension preferredLayoutSize(final Container parent) {
       synchronized (parent.getTreeLock()) {
           final Insets ins = parent.getInsets();
           final Component[] comps = parent.getComponents();
           int height = 0;
           int width = 0;
           for (int i = 0; i < comps.length; i++) {
               if ((comps[i].isVisible() == false) && this.ignoreInvisible) {
                   continue;
               }
               final Dimension pref = comps[i].getPreferredSize();
               if (pref.height > height) {
                   height = pref.height;
               }
               if (pref.width > width) {
                   width = pref.width;
               }
           }
           return new Dimension(width + ins.left + ins.right,
               height + ins.top + ins.bottom);
       }
   }

}


 </source>
   
  
 
  



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

   <source lang="java">
   

/*

* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 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:
* 
*
 * 
 * Login:    _______________ 
 * Password: _______________
 * 
 * 
* 
* Basically two (or more) columns of different, but constant, widths. Note:
* all columns must be the same height! .
* <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. Note:  As with GridLayout, the
* number of items added must  be an even multiple of the number of
* columns. If not, exceptions may be thrown!
* 
* @author Ian F. Darwin, http://www.darwinsys.ru/
* @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);
   }
 }

}



 </source>
   
  
 
  



Center Layout

   <source lang="java">
   

/*

   GNU LESSER GENERAL PUBLIC LICENSE
   Copyright (C) 2006 The Lobo Project
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
   You should have received a copy of the GNU Lesser General Public
   License along with this library; if not, write to the Free Software
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   Contact info: lobochief@users.sourceforge.net
  • /

/*

* Created on Mar 19, 2005
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.LayoutManager; /**

* @author J. H. S.
*/

public class CenterLayout implements LayoutManager {

   public void addLayoutComponent(String arg0, Component arg1) {
   }
   public void removeLayoutComponent(Component arg0) {
   }
   public Dimension preferredLayoutSize(Container arg0) {
     java.awt.Insets insets = arg0.getInsets();
       int count = arg0.getComponentCount();
       if(count > 0) {
           Dimension d = arg0.getComponent(0).getPreferredSize();
           return new Dimension(d.width + insets.left + insets.right,
                          d.height + insets.top + insets.bottom);
       }
       else {
           return new Dimension(insets.left + insets.right, insets.top + insets.bottom);
       }
   }
   /* (non-Javadoc)
    * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
    */
   public Dimension minimumLayoutSize(Container arg0) {
     java.awt.Insets insets = arg0.getInsets();
       int count = arg0.getComponentCount();
       if(count > 0) {
           Dimension d = arg0.getComponent(0).getMinimumSize();
           return new Dimension(d.width + insets.left + insets.right,
              d.height + insets.top + insets.bottom);
       }
       else {
           return new Dimension(insets.left + insets.right, insets.top + insets.bottom);
       }
   }
   /* (non-Javadoc)
    * @see java.awt.LayoutManager#layoutContainer(java.awt.Container)
    */
   public void layoutContainer(Container container) {
       int count = container.getComponentCount();
       if(count > 0) {
           Component child = container.getComponent(0); 
           java.awt.Insets insets = container.getInsets();
           int availWidth = container.getWidth() - insets.left - insets.right;
           int availHeight = container.getHeight() - insets.top - insets.bottom;
           Dimension preferredSize = child.getPreferredSize();
           double preferredWidth = preferredSize.getWidth();
           double preferredHeight = preferredSize.getHeight();
           int width;
           int height;
           int x;
           int y;
           if(preferredWidth < availWidth) {
             x = (int) Math.round(insets.left + (availWidth - preferredWidth) / 2);
             width = (int) Math.round(preferredWidth);
           }
           else {
             x = insets.left;
             width = availWidth;
           }
           if(preferredHeight < availHeight) {
             y = (int) Math.round(insets.top + (availHeight - preferredHeight) / 2);
             height = (int) Math.round(preferredHeight);
           }
           else {
             y = insets.top;
             height = availHeight;
           }
           child.setBounds(x, y, width, height);
       }
   }
   
   private static CenterLayout instance = new CenterLayout();
   
   public static CenterLayout getInstance() {
     return instance;
   }

}



 </source>
   
  
 
  



ColumnLayout

   <source lang="java">
   

/*

* Copyright (c) 2000 David Flanagan.  All rights reserved.
* This code is from the book Java Examples in a Nutshell, 2nd Edition.
* It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
* You may study, use, and modify it for any non-commercial purpose.
* You may distribute it non-commercially as long as you retain this notice.
* For a commercial use license, or to purchase the book (recommended),
* visit http://www.davidflanagan.ru/javaexamples2.
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.Insets; import java.awt.LayoutManager2; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; /**

* This LayoutManager arranges the components into a column. Components are
* always given their preferred size.
* 
* When you create a ColumnLayout, you may specify four values: margin_height --
* how much space to leave on top and bottom margin_width -- how much space to
* leave on left and right spacing -- how much vertical space to leave between
* items alignment -- the horizontal position of the components:
* ColumnLayout.LEFT -- left-justify the components ColumnLayout.CENTER --
* horizontally center the components ColumnLayout.RIGHT -- right-justify the
* components
* 
* You never call the methods of a ColumnLayout object. Just create one and make
* it the layout manager for your container by passing it to the addLayout()
* method of the Container object.
*/

public class ColumnLayout implements LayoutManager2 {

 protected int margin_height;
 protected int margin_width;
 protected int spacing;
 protected int alignment;
 // Constants for the alignment argument to the constructor.
 public static final int LEFT = 0;
 public static final int CENTER = 1;
 public static final int RIGHT = 2;
 /** The constructor. See comment above for meanings of these arguments */
 public ColumnLayout(int margin_height, int margin_width, int spacing,
     int alignment) {
   this.margin_height = margin_height;
   this.margin_width = margin_width;
   this.spacing = spacing;
   this.alignment = alignment;
 }
 /**
  * A default constructor that creates a ColumnLayout using 5-pixel margin
  * width and height, 5-pixel spacing, and left alignment
  */
 public ColumnLayout() {
   this(5, 5, 5, LEFT);
 }
 /**
  * The method that actually performs the layout. Called by the Container
  */
 public void layoutContainer(Container parent) {
   Insets insets = parent.getInsets();
   Dimension parent_size = parent.getSize();
   Component kid;
   int nkids = parent.getComponentCount();
   int x0 = insets.left + margin_width; // The base X position
   int x;
   int y = insets.top + margin_height; // Start at the top of the column
   for (int i = 0; i < nkids; i++) { // Loop through the kids
     kid = parent.getComponent(i); // Get the kid
     if (!kid.isVisible())
       continue; // Skip hidden ones
     Dimension pref = kid.getPreferredSize(); // How big is it?
     switch (alignment) { // Compute X coordinate
     default:
     case LEFT:
       x = x0;
       break;
     case CENTER:
       x = (parent_size.width - pref.width) / 2;
       break;
     case RIGHT:
       x = parent_size.width - insets.right - margin_width
           - pref.width;
       break;
     }
     // Set the size and position of this kid
     kid.setBounds(x, y, pref.width, pref.height);
     y += pref.height + spacing; // Get Y position of the next one
   }
 }
 /** The Container calls this to find out how big the layout should to be */
 public Dimension preferredLayoutSize(Container parent) {
   return layoutSize(parent, 1);
 }
 /** The Container calls this to find out how big the layout must be */
 public Dimension minimumLayoutSize(Container parent) {
   return layoutSize(parent, 2);
 }
 /** The Container calls this to find out how big the layout can be */
 public Dimension maximumLayoutSize(Container parent) {
   return layoutSize(parent, 3);
 }
 // Compute min, max, or preferred size of all the visible children
 protected Dimension layoutSize(Container parent, int sizetype) {
   int nkids = parent.getComponentCount();
   Dimension size = new Dimension(0, 0);
   Insets insets = parent.getInsets();
   int num_visible_kids = 0;
   // Compute maximum width and total height of all visible kids
   for (int i = 0; i < nkids; i++) {
     Component kid = parent.getComponent(i);
     Dimension d;
     if (!kid.isVisible())
       continue;
     num_visible_kids++;
     if (sizetype == 1)
       d = kid.getPreferredSize();
     else if (sizetype == 2)
       d = kid.getMinimumSize();
     else
       d = kid.getMaximumSize();
     if (d.width > size.width)
       size.width = d.width;
     size.height += d.height;
   }
   // Now add in margins and stuff
   size.width += insets.left + insets.right + 2 * margin_width;
   size.height += insets.top + insets.bottom + 2 * margin_height;
   if (num_visible_kids > 1)
     size.height += (num_visible_kids - 1) * spacing;
   return size;
 }
 // Other LayoutManager(2) methods that are unused by this class
 public void addLayoutComponent(String constraint, Component comp) {
 }
 public void addLayoutComponent(Component comp, Object constraint) {
 }
 public void removeLayoutComponent(Component comp) {
 }
 public void invalidateLayout(Container parent) {
 }
 public float getLayoutAlignmentX(Container parent) {
   return 0.5f;
 }
 public float getLayoutAlignmentY(Container parent) {
   return 0.5f;
 }

} class ColumnLayoutPane extends JPanel {

 public ColumnLayoutPane() {
   // Get rid of the default layout manager.
   // We"ll arrange the components ourselves.
   this.setLayout(new ColumnLayout(5, 5, 10, ColumnLayout.RIGHT));
   // Create some buttons and set their sizes and positions explicitly
   for (int i = 0; i < 6; i++) {
     int pointsize = 8 + i * 2;
     JButton b = new JButton("Point size " + pointsize);
     b.setFont(new Font("helvetica", Font.BOLD, pointsize));
     this.add(b);
   }
 }
 public static void main(String[] a) {
   JFrame f = new JFrame();
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   f.setContentPane(new ColumnLayoutPane());
   f.pack();
   f.setVisible(true);
 }
 

}




 </source>
   
  
 
  



Compents are laid out in a circle.

   <source lang="java">
 

/*

* JCommon : a free general purpose class library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
* 
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it 
* under the terms of the GNU Lesser General Public License as published by 
* the Free Software Foundation; either version 2.1 of the License, or 
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but 
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
* USA.  
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
* in the United States and other countries.]
* 
* -----------------
* RadialLayout.java
* -----------------
* (C) Copyright 2003, 2004, by Bryan Scott (for Australian Antarctic Division).
*
* Original Author:  Bryan Scott (for Australian Antarctic Division);
* Contributor(s):   David Gilbert (for Object Refinery Limited);
*
*
* Changes:
* --------
* 30-Jun-2003 : Version 1 (BS);
* 24-Jul-2003 : Completed missing Javadocs (DG);
*
*/

import java.awt.Checkbox; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Frame; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.Panel; import java.io.Serializable; /**

* RadialLayout is a component layout manager.  Compents are laid out in a
* circle. If only one component is contained in the layout it is positioned
* centrally, otherwise components are evenly spaced around the centre with
* the first component placed to the North.
*<P>
* This code was developed to display CTD rosette firing control
*
* WARNING: Not thoughly tested, use at own risk.
* 
* @author Bryan Scott (for Australian Antarctic Division)
*/

public class RadialLayout implements LayoutManager, Serializable {

   /** For serialization. */
   private static final long serialVersionUID = -7582156799248315534L;
   
   /** The minimum width. */
   private int minWidth = 0;
   
   /** The minimum height. */
   private int minHeight = 0;
   
   /** The maximum component width. */
   private int maxCompWidth = 0;
   
   /** The maximum component height. */
   private int maxCompHeight = 0;
   
   /** The preferred width. */
   private int preferredWidth = 0;
   
   /** The preferred height. */
   private int preferredHeight = 0;
   
   /** Size unknown flag. */
   private boolean sizeUnknown = true;
   /** 
    * Constructs this layout manager with default properties. 
    */
   public RadialLayout() {
       super();
   }
   /**
    * Not used.
    *
    * @param comp  the component.
    */
   public void addLayoutComponent(final Component comp) {
       // not used
   }
   /**
    * Not used.
    *
    * @param comp  the component.
    */
   public void removeLayoutComponent(final Component comp) {
       // not used
   }
   /**
    * Not used.
    *
    * @param name  the component name.
    * @param comp  the component.
    */
   public void addLayoutComponent(final String name, final Component comp) {
       // not used
   }
   /**
    * Not used.
    *
    * @param name  the component name.
    * @param comp  the component.
    */
   public void removeLayoutComponent(final String name, final Component comp) {
       // not used
   }
   /**
    * Sets the sizes attribute of the RadialLayout object.
    *
    * @param  parent  the parent.
    * 
    * @see LayoutManager
    */
   private void setSizes(final Container parent) {
       final int nComps = parent.getComponentCount();
       //Reset preferred/minimum width and height.
       this.preferredWidth = 0;
       this.preferredHeight = 0;
       this.minWidth = 0;
       this.minHeight = 0;
       for (int i = 0; i < nComps; i++) {
           final Component c = parent.getComponent(i);
           if (c.isVisible()) {
               final Dimension d = c.getPreferredSize();
               if (this.maxCompWidth < d.width) {
                   this.maxCompWidth = d.width;
               }
               if (this.maxCompHeight < d.height) {
                   this.maxCompHeight = d.height;
               }
               this.preferredWidth += d.width;
               this.preferredHeight += d.height;
           }
       }
       this.preferredWidth  = this.preferredWidth / 2;
       this.preferredHeight = this.preferredHeight / 2;
       this.minWidth = this.preferredWidth;
       this.minHeight = this.preferredHeight;
   }
   /**
    * Returns the preferred size.
    *
    * @param parent  the parent.
    *
    * @return The preferred size.
    * @see LayoutManager
    */
   public Dimension preferredLayoutSize(final Container parent) {
       final Dimension dim = new Dimension(0, 0);
       setSizes(parent);
       //Always add the container"s insets!
       final Insets insets = parent.getInsets();
       dim.width = this.preferredWidth + insets.left + insets.right;
       dim.height = this.preferredHeight + insets.top + insets.bottom;
       this.sizeUnknown = false;
       return dim;
   }
   /**
    * Returns the minimum size.
    *
    * @param parent  the parent.
    *
    * @return The minimum size.
    * @see LayoutManager
    */
   public Dimension minimumLayoutSize(final Container parent) {
       final Dimension dim = new Dimension(0, 0);
       //Always add the container"s insets!
       final Insets insets = parent.getInsets();
       dim.width = this.minWidth + insets.left + insets.right;
       dim.height = this.minHeight + insets.top + insets.bottom;
       this.sizeUnknown = false;
       return dim;
   }
  /**
   * This is called when the panel is first displayed, and every time its size
   * changes.
   * Note: You CAN"T assume preferredLayoutSize or minimumLayoutSize will be
   * called -- in the case of applets, at least, they probably won"t be.
   *
   * @param  parent  the parent.
   * @see LayoutManager
   */
   public void layoutContainer(final Container parent) {
       final Insets insets = parent.getInsets();
       final int maxWidth = parent.getSize().width 
           - (insets.left + insets.right);
       final int maxHeight = parent.getSize().height 
           - (insets.top + insets.bottom);
       final int nComps = parent.getComponentCount();
       int x = 0;
       int y = 0;
       // Go through the components" sizes, if neither preferredLayoutSize nor
       // minimumLayoutSize has been called.
       if (this.sizeUnknown) {
           setSizes(parent);
       }
       if (nComps < 2) {
           final Component c = parent.getComponent(0);
           if (c.isVisible()) {
               final Dimension d = c.getPreferredSize();
               c.setBounds(x, y, d.width, d.height);
           }
       } 
       else {
           double radialCurrent = Math.toRadians(90);
           final double radialIncrement = 2 * Math.PI / nComps;
           final int midX = maxWidth / 2;
           final int midY = maxHeight / 2;
           final int a = midX - this.maxCompWidth;
           final int b = midY - this.maxCompHeight;
           for (int i = 0; i < nComps; i++) {
               final Component c = parent.getComponent(i);
               if (c.isVisible()) {
                   final Dimension d = c.getPreferredSize();
                   x = (int) (midX
                              - (a * Math.cos(radialCurrent))
                              - (d.getWidth() / 2)
                              + insets.left);
                   y = (int) (midY
                              - (b * Math.sin(radialCurrent))
                              - (d.getHeight() / 2)
                              + insets.top);
                   // Set the component"s size and position.
                   c.setBounds(x, y, d.width, d.height);
               }
               radialCurrent += radialIncrement;
           }
       }
   }
   /**
    * Returns the class name.
    * 
    * @return The class name.
    */
   public String toString() {
       return getClass().getName();
   }
   /**
    * Run a demonstration.
    *
    * @param args  ignored.
    * 
    * @throws Exception when an error occurs.
    */
   public static void main(final String[] args) throws Exception {
       final Frame frame = new Frame();
       final Panel panel = new Panel();
       panel.setLayout(new RadialLayout());
       panel.add(new Checkbox("One"));
       panel.add(new Checkbox("Two"));
       panel.add(new Checkbox("Three"));
       panel.add(new Checkbox("Four"));
       panel.add(new Checkbox("Five"));
       panel.add(new Checkbox("One"));
       panel.add(new Checkbox("Two"));
       panel.add(new Checkbox("Three"));
       panel.add(new Checkbox("Four"));
       panel.add(new Checkbox("Five"));
       frame.add(panel);
       frame.setSize(300, 500);
       frame.setVisible(true);
   }

}


 </source>
   
  
 
  



Customized layout manager

   <source lang="java">
   

import java.awt.Button; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; public class CircleLayoutTest extends JFrame {

 public CircleLayoutTest() {
   setTitle("CircleLayoutTest");
   setSize(300, 300);
   addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   getContentPane().setLayout(new CircleLayout());
   getContentPane().add(new Button("3"));
   getContentPane().add(new Button("4"));
   getContentPane().add(new Button("5"));
   getContentPane().add(new Button("6"));
   getContentPane().add(new Button("7"));
   getContentPane().add(new Button("8"));
   getContentPane().add(new Button("9"));
   getContentPane().add(new Button("10"));
   getContentPane().add(new Button("11"));
   getContentPane().add(new Button("12"));
   getContentPane().add(new Button("1"));
   getContentPane().add(new Button("2"));
 }
 public static void main(String[] args) {
   JFrame f = new CircleLayoutTest();
   f.show();
 }

} class CircleLayout implements LayoutManager {

 private int minWidth = 0;
 private int minHeight = 0;
 private int preferredWidth = 0, preferredHeight = 0;
 private boolean sizesSet = false;
 private int maxComponentWidth = 0;
 private int maxComponentHeight = 0;
 public void addLayoutComponent(String name, Component comp) {
 }
 public void removeLayoutComponent(Component comp) {
 }
 public void setSizes(Container parent) {
   if (sizesSet)
     return;
   int comCount = parent.getComponentCount();
   for (int i = 0; i < comCount; i++) {
     Component c = parent.getComponent(i);
     if (c.isVisible()) {
       Dimension size = c.getPreferredSize();
       maxComponentWidth = Math.max(maxComponentWidth, size.width);
       maxComponentHeight = Math.max(maxComponentWidth, size.height);
       preferredHeight += size.height;
     }
   }
   preferredHeight += maxComponentHeight;
   preferredWidth = 2 * maxComponentWidth;
   minHeight = preferredHeight;
   minWidth = preferredWidth;
   sizesSet = true;
 }
 public Dimension preferredLayoutSize(Container parent) {
   Dimension dim = new Dimension(0, 0);
   setSizes(parent);
   Insets insets = parent.getInsets();
   dim.width = preferredWidth + insets.left + insets.right;
   dim.height = preferredHeight + insets.top + insets.bottom;
   return dim;
 }
 public Dimension minimumLayoutSize(Container parent) {
   return preferredLayoutSize(parent);
 }
 public void layoutContainer(Container parent) {
   Insets insets = parent.getInsets();
   int containerWidth = parent.getSize().width - insets.left
       - insets.right;
   int containerHeight = parent.getSize().height - insets.top
       - insets.bottom;
   int xradius = (containerWidth - maxComponentWidth) / 2;
   int yradius = (containerHeight - maxComponentHeight) / 2;
   setSizes(parent);
   int centerX = insets.left + containerWidth / 2;
   int centerY = insets.top + containerHeight / 2;
   int comCount = parent.getComponentCount();
   for (int i = 0; i < comCount; i++) {
     Component c = parent.getComponent(i);
     if (c.isVisible()) {
       Dimension size = c.getPreferredSize();
       double angle = 2 * Math.PI * i / comCount;
       int x = centerX + (int) (Math.cos(angle) * xradius);
       int y = centerY + (int) (Math.sin(angle) * yradius);
       c.setBounds(x - size.width / 2, y - size.height / 2, size.width,
           size.height);
     }
   }
 }

}



 </source>
   
  
 
  



Custom Layout Demo

   <source lang="java">
   

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution 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.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

/*

* CustomLayoutDemo.java is a 1.4 application that requires one other file:
* DiagonalLayout.java
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import javax.swing.JButton; import javax.swing.JFrame; public class CustomLayoutDemo {

 public static void addComponentsToPane(Container pane) {
   pane.setLayout(new DiagonalLayout());
   pane.add(new JButton("Button 1"));
   pane.add(new JButton("Button 2"));
   pane.add(new JButton("Button 3"));
   pane.add(new JButton("Button 4"));
   pane.add(new JButton("Button 5"));
 }
 /**
  * Create the GUI and show it. For thread safety, this method should be
  * invoked from the event-dispatching thread.
  */
 private static void createAndShowGUI() {
   //Make sure we have nice window decorations.
   JFrame.setDefaultLookAndFeelDecorated(true);
   //Create and set up the window.
   JFrame frame = new JFrame("CustomLayoutDemo");
   frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   //Set up the content pane.
   addComponentsToPane(frame.getContentPane());
   //Display the window.
   frame.pack();
   frame.setVisible(true);
 }
 public static void main(String[] args) {
   //Schedule a job for the event-dispatching thread:
   //creating and showing this application"s GUI.
   javax.swing.SwingUtilities.invokeLater(new Runnable() {
     public void run() {
       createAndShowGUI();
     }
   });
 }

} /*

* 1.2+ version. Used by CustomLayoutDemo.java.
*/

class DiagonalLayout implements LayoutManager {

 private int vgap;
 private int minWidth = 0, minHeight = 0;
 private int preferredWidth = 0, preferredHeight = 0;
 private boolean sizeUnknown = true;
 public DiagonalLayout() {
   this(5);
 }
 public DiagonalLayout(int v) {
   vgap = v;
 }
 /* Required by LayoutManager. */
 public void addLayoutComponent(String name, Component comp) {
 }
 /* Required by LayoutManager. */
 public void removeLayoutComponent(Component comp) {
 }
 private void setSizes(Container parent) {
   int nComps = parent.getComponentCount();
   Dimension d = null;
   //Reset preferred/minimum width and height.
   preferredWidth = 0;
   preferredHeight = 0;
   minWidth = 0;
   minHeight = 0;
   for (int i = 0; i < nComps; i++) {
     Component c = parent.getComponent(i);
     if (c.isVisible()) {
       d = c.getPreferredSize();
       if (i > 0) {
         preferredWidth += d.width / 2;
         preferredHeight += vgap;
       } else {
         preferredWidth = d.width;
       }
       preferredHeight += d.height;
       minWidth = Math.max(c.getMinimumSize().width, minWidth);
       minHeight = preferredHeight;
     }
   }
 }
 /* Required by LayoutManager. */
 public Dimension preferredLayoutSize(Container parent) {
   Dimension dim = new Dimension(0, 0);
   int nComps = parent.getComponentCount();
   setSizes(parent);
   //Always add the container"s insets!
   Insets insets = parent.getInsets();
   dim.width = preferredWidth + insets.left + insets.right;
   dim.height = preferredHeight + insets.top + insets.bottom;
   sizeUnknown = false;
   return dim;
 }
 /* Required by LayoutManager. */
 public Dimension minimumLayoutSize(Container parent) {
   Dimension dim = new Dimension(0, 0);
   int nComps = parent.getComponentCount();
   //Always add the container"s insets!
   Insets insets = parent.getInsets();
   dim.width = minWidth + insets.left + insets.right;
   dim.height = minHeight + insets.top + insets.bottom;
   sizeUnknown = false;
   return dim;
 }
 /* Required by LayoutManager. */
 /*
  * This is called when the panel is first displayed, and every time its size
  * changes. Note: You CAN"T assume preferredLayoutSize or minimumLayoutSize
  * will be called -- in the case of applets, at least, they probably won"t
  * be.
  */
 public void layoutContainer(Container parent) {
   Insets insets = parent.getInsets();
   int maxWidth = parent.getWidth() - (insets.left + insets.right);
   int maxHeight = parent.getHeight() - (insets.top + insets.bottom);
   int nComps = parent.getComponentCount();
   int previousWidth = 0, previousHeight = 0;
   int x = 0, y = insets.top;
   int rowh = 0, start = 0;
   int xFudge = 0, yFudge = 0;
   boolean oneColumn = false;
   // Go through the components" sizes, if neither
   // preferredLayoutSize nor minimumLayoutSize has
   // been called.
   if (sizeUnknown) {
     setSizes(parent);
   }
   if (maxWidth <= minWidth) {
     oneColumn = true;
   }
   if (maxWidth != preferredWidth) {
     xFudge = (maxWidth - preferredWidth) / (nComps - 1);
   }
   if (maxHeight > preferredHeight) {
     yFudge = (maxHeight - preferredHeight) / (nComps - 1);
   }
   for (int i = 0; i < nComps; i++) {
     Component c = parent.getComponent(i);
     if (c.isVisible()) {
       Dimension d = c.getPreferredSize();
       // increase x and y, if appropriate
       if (i > 0) {
         if (!oneColumn) {
           x += previousWidth / 2 + xFudge;
         }
         y += previousHeight + vgap + yFudge;
       }
       // If x is too large,
       if ((!oneColumn)
           && (x + d.width) > (parent.getWidth() - insets.right)) {
         // reduce x to a reasonable number.
         x = parent.getWidth() - insets.bottom - d.width;
       }
       // If y is too large,
       if ((y + d.height) > (parent.getHeight() - insets.bottom)) {
         // do nothing.
         // Another choice would be to do what we do to x.
       }
       // Set the component"s size and position.
       c.setBounds(x, y, d.width, d.height);
       previousWidth = d.width;
       previousHeight = d.height;
     }
   }
 }
 public String toString() {
   String str = "";
   return getClass().getName() + "[vgap=" + vgap + str + "]";
 }

}



 </source>
   
  
 
  



Custom layout: EdgeLayout

   <source lang="java">
   

/* Code from Desktop Java Live Source URL: http://www.sourcebeat.ru/downloads/

  • /

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager2; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class EdgeLayoutExample {

   public static JPanel createPanel() {
       JPanel outerPanel = new JPanel();
       outerPanel.setLayout(new EdgeLayout());
       outerPanel.add(new JButton("West1"), EdgeLayout.WEST);
       outerPanel.add(new JButton("North1"), EdgeLayout.NORTH);
       outerPanel.add(new JButton("West2"), EdgeLayout.WEST);
       outerPanel.add(new JButton("North2"), EdgeLayout.NORTH);
       outerPanel.add(new JButton("East1"), EdgeLayout.EAST);
       outerPanel.add(new JButton("South1"), EdgeLayout.SOUTH);
       outerPanel.add(new JButton("West3"), EdgeLayout.WEST);
       outerPanel.add(new JButton("West4"), EdgeLayout.WEST);
       outerPanel.add(new JButton("South2"), EdgeLayout.SOUTH);
       outerPanel.add(new JButton("South3"), EdgeLayout.SOUTH);
       outerPanel.add(new JButton("Center1"), EdgeLayout.CENTER);
       return outerPanel;
   }
   public static void main(String[] a){
     JFrame f = new JFrame();
     f.setDefaultCloseOperation(1);
     f.add(createPanel());
     f.pack();
     f.setVisible(true);
   } 

}

class EdgeLayout implements LayoutManager2, java.io.Serializable {

   private List components = new ArrayList();
   private HashMap constraints = new HashMap();
   public static final String CENTER = "center";
   public static final String NORTH = "north";
   public static final String SOUTH = "south";
   public static final String EAST = "east";
   public static final String WEST = "west";
   public void addLayoutComponent(Component comp, Object constraints) {
       synchronized (comp.getTreeLock()) {
           if (constraints instanceof String && comp != null) {
               this.ruponents.add(comp);
               this.constraints.put(comp, constraints);
           } else {
               throw new IllegalArgumentException("Invalid component constraints.");
           }
       }
   }
   public Dimension maximumLayoutSize(Container target) {
       //Return a very large size since this layout manager will fill all available space.
       return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
   }
   public float getLayoutAlignmentX(Container target) {
       //Centered on the X
       return (float) 0.5;
   }
   public float getLayoutAlignmentY(Container target) {
       //Centered on the Y
       return (float) 0.5;
   }
   public void invalidateLayout(Container target) {
       //There is no caching in EdgeLayout to there is nothing to invalidate
   }
   public void addLayoutComponent(String name, Component comp) {
       throw new IllegalArgumentException("EdgeLayout only supports addition with contraints.");
   }
   public void removeLayoutComponent(Component comp) {
       synchronized (comp.getTreeLock()) {
           this.ruponents.remove(comp);
           this.constraints.remove(comp);
       }
   }
   public Dimension preferredLayoutSize(Container parent) {
       synchronized (parent.getTreeLock()) {
           int width = 0;
           int height = 0;
           //Add the preferred widths of all EAST/WEST components
           //Add the preferred height of all NORTH/SOUTH components
           for (int i = 0; i < this.ruponents.size(); i++) {
               Component c = (Component) this.ruponents.get(i);
               if (this.constraints.get(c).equals(WEST) || this.constraints.get(c).equals(EAST)) {
                   width += c.getPreferredSize().getWidth();
               } else {
                   height += c.getPreferredSize().getHeight();
               }
           }
           width += parent.getInsets().right + parent.getInsets().left;
           height += parent.getInsets().top + parent.getInsets().bottom;
           return new Dimension(width, height);
       }
   }
   public Dimension minimumLayoutSize(Container parent) {
       synchronized (parent.getTreeLock()) {
           int width = 0;
           int height = 0;
           //Add the minimum  widths of all EAST/WEST components
           //Add the minimum height of all NORTH/SOUTH components
           for (int i = 0; i < this.ruponents.size(); i++) {
               Component c = (Component) this.ruponents.get(i);
               if (this.constraints.get(c).equals(WEST) || this.constraints.get(c).equals(EAST)) {
                   width += c.getMinimumSize().getWidth();
               } else {
                   height += c.getMinimumSize().getHeight();
               }
           }
           width += parent.getInsets().right + parent.getInsets().left;
           height += parent.getInsets().top + parent.getInsets().bottom;
           return new Dimension(width, height);
       }
   }
   public void layoutContainer(Container parent) {
       synchronized (parent.getTreeLock()) {
           Insets insets = parent.getInsets();
           int top = insets.top;
           int left = insets.left;
           Dimension minimumSize = minimumLayoutSize(parent);
           int height = minimumSize.height;
           int width = minimumSize.width;
           int availableHeight = parent.getHeight() - insets.bottom - insets.top;
           int availableWidth = parent.getWidth() - insets.left - insets.right;
           if (height < availableHeight) {
               height = availableHeight;
           }
           if (width < availableWidth) {
               width = availableWidth;
           }
           int bottom = availableHeight;
           int right = availableWidth;
           Dimension preferredSize = preferredLayoutSize(parent);
           int preferredWidthAvailable = width - preferredSize.width;
           int preferredHeightAvailable = height - preferredSize.height;
           Component centerComp = null;
           for (int i = 0; i < this.ruponents.size(); i++) {
               Component c = (Component) this.ruponents.get(i);
               String constraint = (String) this.constraints.get(c);
               if (constraint.equals(CENTER)) {
                   centerComp = c;
               } else {
                   int compHeight;
                   int compWidth;
                   int xOrigin;
                   int yOrigin;
                   if (constraint.equals(NORTH) || constraint.equals(SOUTH)) {
                       compWidth = width;
                       if (preferredHeightAvailable > 0) {
                           int preferredHeightNeeded = c.getPreferredSize().height - c.getMinimumSize().height;
                           if (preferredHeightAvailable > preferredHeightNeeded) {
                               compHeight = c.getPreferredSize().height;
                               preferredHeightAvailable -= preferredHeightNeeded;
                           } else {
                               compHeight = c.getMinimumSize().height + preferredHeightAvailable;
                               preferredHeightAvailable = 0;
                           }
                       } else {
                           compHeight = c.getMinimumSize().height;
                       }
                       height = height - compHeight;
                       xOrigin = left;
                       if (constraint.equals(NORTH)) {
                           yOrigin = top;
                           top += compHeight;
                       } else {
                           yOrigin = bottom - compHeight;
                           bottom = yOrigin;
                       }
                   } else {
                       compHeight = height;
                       if (preferredWidthAvailable > 0) {
                           int preferredWidthNeeded = c.getPreferredSize().width - c.getMinimumSize().width;
                           if (preferredWidthAvailable > preferredWidthNeeded) {
                               compWidth = c.getPreferredSize().width;
                               preferredWidthAvailable -= preferredWidthNeeded;
                           } else {
                               compWidth = c.getMinimumSize().width + preferredWidthAvailable;
                               preferredWidthAvailable = 0;
                           }
                       } else {
                           compWidth = c.getMinimumSize().width;
                       }
                       width = width - compWidth;
                       yOrigin = top;
                       if (constraint.equals(WEST)) {
                           xOrigin = left;
                           left += compWidth;
                       } else {
                           xOrigin = right - compWidth;
                           right = xOrigin;
                       }
                   }
                   c.setSize(compWidth, compHeight);
                   c.setBounds(xOrigin, yOrigin, compWidth, compHeight);
               }
               if (centerComp != null) {
                   c.setSize(width, height);
                   c.setBounds(left, top, width, height);
               }
           }
       }
   }

}



 </source>
   
  
 
  



DividerLayout is layout that divides two components with the column of actions

   <source lang="java">
   

/*

* $Id: DividerLayout.java,v 1.1.1.1 2005/04/07 18:36:20 pocho Exp $
*/

// Revised from javautils swing; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager2; import java.awt.Rectangle; /**

* <p>
* DividerLayout is layout that divides two components with the
* column of actions. It is especially usefull for components that contains
* two lists of elements and buttons for transfering elements between these
* two lists.
*

*

* Components are indicated as {@link #WEST}, {@link #EAST} and {@link #CENTER}. *

* 
* @version $Name:  $ - $Revision: 1.1.1.1 $ - $Date: 2005/04/07 18:36:20 $
* TODO Test
*/

public class DividerLayout implements LayoutManager2 {

 /**
  * Indicates west component
  */
 public final static String WEST = "WEST";
 /**
  * indicates east component
  */
 public final static String EAST = "EAST";
 /**
  * indicates center component
  */
 public final static String CENTER = "CENTER";
 /**
  * west component
  */
 protected Component westComponent;
 
 /**
  * center component
  */
 protected Component centerComponent;
 
 /**
  * east component
  */
 protected Component eastComponent;
 
 /**
  * Adds a component to specified position.
  */
 public void addLayoutComponent(Component comp, Object constraints) {
   if (WEST.equalsIgnoreCase((String) constraints)) {
     westComponent = comp;
   }
   else if (CENTER.equalsIgnoreCase((String) constraints)) {
     centerComponent = comp;
   }
   else if (EAST.equalsIgnoreCase((String) constraints)) {
     eastComponent = comp;
   }
 }
 /**
  * @see java.awt.LayoutManager2#maximumLayoutSize(java.awt.Container)
  */
 public Dimension maximumLayoutSize(Container target) {
   Dimension size;
   int width = 0;
   int height = 0;
   if ((westComponent != null) && (westComponent.isVisible())) {
     size = westComponent.getMaximumSize();
     width = Math.max(width, size.width);
     height = Math.max(height, size.height);
   }
   if ((eastComponent != null) && (eastComponent.isVisible())) {
     size = eastComponent.getMaximumSize();
     width = Math.max(width, size.width);
     height = Math.max(height, size.height);
   }
   width *= 2;
   if ((centerComponent != null) && (centerComponent.isVisible())) {
     size = centerComponent.getPreferredSize();
     width += size.width;
     height = Math.max(height, size.height);
   }
   return new Dimension(width, height);
 }
 /**
  * @see java.awt.LayoutManager2#getLayoutAlignmentX(java.awt.Container)
  */
 public float getLayoutAlignmentX(Container target) {
   return 0.0f;
 }
 /**
  * @see java.awt.LayoutManager2#getLayoutAlignmentY(java.awt.Container)
  */
 public float getLayoutAlignmentY(Container target) {
   return 0.0f;
 }
 /**
  * @see java.awt.LayoutManager2#invalidateLayout(java.awt.Container)
  */
 public void invalidateLayout(Container target) {}
 /**
  * @see java.awt.LayoutManager#addLayoutComponent(java.lang.String, java.awt.ruponent)
  */
 public void addLayoutComponent(String name, Component comp) {
   addLayoutComponent(comp, name);
 }
 /**
  * @see java.awt.LayoutManager#removeLayoutComponent(java.awt.ruponent)
  */
 public void removeLayoutComponent(Component comp) {
   if (comp == westComponent) {
     westComponent = null;
   }
   else if (comp == centerComponent) {
     centerComponent = null;
   }
   else if (comp == eastComponent) {
     centerComponent = null;
   }
 }
 
 /**
  * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container)
  */
 public Dimension preferredLayoutSize(Container parent) {
   Dimension size;
   int width = 0;
   int height = 0;
   if ((westComponent != null) && (westComponent.isVisible())) {
     size = westComponent.getPreferredSize();
     width = Math.max(width, size.width);
     height = Math.max(height, size.height);
   }
   if ((eastComponent != null) && (eastComponent.isVisible())) {
     size = eastComponent.getPreferredSize();
     width = Math.max(width, size.width);
     height = Math.max(height, size.height);
   }
   width *= 2;
   if ((centerComponent != null) && (centerComponent.isVisible())) {
     size = centerComponent.getPreferredSize();
     width += size.width;
     height = Math.max(height, size.height);
   }
   return new Dimension(width, height);
 }
 /**
  * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container)
  */
 public Dimension minimumLayoutSize(Container parent) {
   Dimension size;
   int width = 0;
   int height = 0;
   if ((westComponent != null) && (westComponent.isVisible())) {
     size = westComponent.getMinimumSize();
     width = Math.max(width, size.width);
     height = Math.max(height, size.height);
   }
   if ((eastComponent != null) && (eastComponent.isVisible())) {
     size = eastComponent.getMinimumSize();
     width = Math.max(width, size.width);
     height = Math.max(height, size.height);
   }
   width *= 2;
   if ((centerComponent != null) && (centerComponent.isVisible())) {
     size = centerComponent.getPreferredSize();
     width += size.width;
     height += Math.max(height, size.height);
   }
   return new Dimension(width, height);
 }
 /**
  * @see java.awt.LayoutManager#layoutContainer(java.awt.Container)
  */
 public void layoutContainer(Container container) {
  Insets insets = container.getInsets();
  Dimension westSize = new Dimension(0, 0);
  Dimension centerSize = new Dimension(0, 0);
  Dimension eastSize = new Dimension(0, 0);
  Rectangle centerBounds = new Rectangle(0, 0, 0, 0);
  Dimension containerSize = container.getSize();
  int centerX = containerSize.width / 2;
  int centerY = containerSize.height / 2;
  if ((centerComponent != null) &&
      (centerComponent.isVisible())) {
    centerSize = centerComponent.getPreferredSize();
    centerSize.width = Math.min(centerSize.width,
        containerSize.width - insets.left -
        insets.right);
    centerSize.height = Math.min(centerSize.height,
        containerSize.height - insets.top -
        insets.bottom);
    centerComponent.setBounds(centerX -
        (centerSize.width / 2),
        centerY - (centerSize.height / 2),
        centerSize.width, centerSize.height);
    centerBounds = centerComponent.getBounds();
  }
  if ((westComponent != null) && (westComponent.isVisible())) {
    westSize = westComponent.getPreferredSize();
  }
  if ((eastComponent != null) && (eastComponent.isVisible())) {
    eastSize = eastComponent.getPreferredSize();
  }
 /* int maxWidth = Math.min(westSize.width, eastSize.width);
  maxWidth = Math.min(maxWidth, (containerSize.width -
      centerBounds.width - insets.left -
      insets.right) / 2);*/
 int maxWidth = (containerSize.width -
      centerBounds.width - insets.left -
      insets.right) / 2;
 /* int maxHeight = Math.min(westSize.height, eastSize.height);
   maxHeight = Math.max(maxHeight, containerSize.height -
      insets.top - insets.bottom);*/
 int maxHeight=containerSize.height - insets.top - insets.bottom;
  if (westComponent != null) {
    westComponent.setBounds(centerBounds.x - maxWidth,
        centerY - (maxHeight / 2),
        maxWidth, maxHeight);
  }
  if (eastComponent != null) {
    eastComponent.setBounds(centerBounds.x +
        centerBounds.width,
        centerY - (maxHeight / 2),
        maxWidth, maxHeight);
  }
}

}



 </source>
   
  
 
  



Flex Layout

   <source lang="java">
   

// FlexLayout // Copyright (C) by Andrea Carboni. // This file may be distributed under the terms of the LGPL license.

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import java.util.StringTokenizer; /** This class implements a combination of the GridBag and Border layouts. The

 * container is subdivided into rows and columns (basically a grid). Each cell
 * can be empty or can contain a component and a component can occupy one or more
 * cells. If a component is smaller than its cell, it can be aligned both horizontally
 * and vertically. The width of a column is the width of its largest component. The
 * height of a row is the height of its tallest component. Furthermore, a row or a
 * column can be expandable, that is its width/height changes depending on the container"s
 * size.

* General design issues:
* First, decide the grid size. Consider that some components (like panels) usually * spread over more cells so it is a good idea to make the grid a little bigger.

* Second, decide which row/column expand (this is done by the setColProp/setRowProp * methods).

* Third, add components to container (layout) giving proper constraints.

* Example:
  * FlexLayout flexL = new FlexLayout(2, 3, 4, 4); //--- (1)
  * flexL.setColProp(1, FlexLayout.EXPAND);        //--- (2)
  * flexL.setRowProp(2, FlexLayout.EXPAND);        //--- (3)
  * setLayout(flexL);                              //--- (4)
  *
  * add("0,0",       new Label("Name"));         //--- (5)
  * add("0,1",       new Label("Surname"));      //--- (6)
  * add("1,0,x",     textField);                 //--- (7)
  * add("1,1,x",     textField);                 //--- (8)
  * add("0,2,x,x,2", panel);                     //--- (9)
  * 

 * Description:
* line 1: creates a FlexLayout of 2 columns and 3 rows. The two 4 represent the gap * between each column and each row. To modify this gap use setXgap and setYgap.
* line 2 & 3: column 1 and row 2 are set to expandable (the default is USEPREFERRED) * remember that row and column id starts from index 0.
* line 4: the layout is added to the container.
* line 5 & 6: add two labels in position (0,0) and (0,1) * line 7 & 8: add two textfields in position (1,0) and (1,1). The x means that the * width will be expanded to occupy all column size. Because column 1 is set to expandable, * when the container is resized the textfields are resized too.
* line 9: adds a panel in position (0,2). Then panel is expanded both horizontally and * vertically and spreads over 2 cells in x direction.

* The complete command string is:
  * "x,y,xa,ya,xs,ys" where:
  *   x,y specify the component position (are the column-row indexes)
  *   xa specifies the x align of the component and can be:
  *     l - for left
  *     c - for center
  *     r - for right
  *     x - exands the component"s width
  *     (default is l)
  *   ya specifies the y align of the component and can be:
  *     t - for top
  *     c - for center
  *     b - for bottom
  *     x - exands the component"s height
  *     (default is c)
  *   xs and ys specify the number or columns/rows occupied by the component (default is 1)
  * 
 * Notes:
* - if a component occupies more than 1 cell in x direction, its preferred width is NOT * taken into account (same for y).
* - if a column / row is empty, its size is set to a default value. This value can be * changed using setXNullgap/setYNullgap methods. *

* Have fun!!! * * @author Andrea Carboni */

public class FlexLayout implements LayoutManager {

  private int xgap;
  private int ygap;
  private int width;
  private int height;
  private int xnullgap = 24;
  private int ynullgap = 24;
  private FlexCell cells[][];
  //--- flags for rows and columns ---
  public static final int USEPREFERRED = 0; //--- default ---
  public static final int EXPAND       = 1;
  private int xflags[];
  private int yflags[];
  private int xpref[];
  private int ypref[];
  //---------------------------------------------------------------------------
  public FlexLayout(int width, int height)
  {
     this(width, height, 4, 4);
  }
  //---------------------------------------------------------------------------
  public FlexLayout(int width, int height, int xgap, int ygap)
  {
     if (width <1 || height <1)
        throw new IllegalArgumentException("width & height must be >0");
     this.width  = width;
     this.height = height;
     this.xgap   = xgap;
     this.ygap   = ygap;
     cells = new FlexCell[width][height];
     xflags = new int[width];
     yflags = new int[height];
     xpref  = new int[width];
     ypref  = new int[height];
  }
  //---------------------------------------------------------------------------
  public void setColProp(int index, int flag)
  {
     xflags[index] = flag;
  }
  //---------------------------------------------------------------------------
  public void setRowProp(int index, int flag)
  {
     yflags[index] = flag;
  }
  //---------------------------------------------------------------------------
  public void setNullGaps(int xgap, int ygap)
  {
     xnullgap = xgap;
     ynullgap = ygap;
  }
  //---------------------------------------------------------------------------
  public void setXgap(int xgap)  {  this.xgap = xgap;  }
  public void setYgap(int ygap)  {  this.ygap = ygap;  }
  public int getXgap()     {  return xgap;     }
  public int getYgap()     {  return ygap;     }
  public int getXNullgap() {  return xnullgap; }
  public int getYNullgap() {  return ynullgap; }
  public int getWidth()    {  return width;    }
  public int getHeight()   {  return height;   }
  //---------------------------------------------------------------------------
  //---
  //--- LayoutManager Interface
  //---
  //---------------------------------------------------------------------------
  public void addLayoutComponent(String name, Component comp)
  {
     StringTokenizer strTk = new StringTokenizer(name,",");
     int x      = 1;
     int y      = 1;
     int xalign = FlexCell.LEFT;
     int yalign = FlexCell.CENTERY;
     int xext   = 1;
     int yext   = 1;
     if (strTk.hasMoreTokens()) x = Integer.parseInt(strTk.nextToken());
     if (strTk.hasMoreTokens()) y = Integer.parseInt(strTk.nextToken());
     if (strTk.hasMoreTokens())
     {
        String align = strTk.nextToken().toLowerCase();
        if (align.equals("l")) xalign = FlexCell.LEFT;
        if (align.equals("c")) xalign = FlexCell.CENTERX;
        if (align.equals("r")) xalign = FlexCell.RIGHT;
        if (align.equals("x")) xalign = FlexCell.EXPANDX;
     }
     if (strTk.hasMoreTokens())
     {
        String align = strTk.nextToken().toLowerCase();
        if (align.equals("t")) yalign = FlexCell.TOP;
        if (align.equals("c")) yalign = FlexCell.CENTERY;
        if (align.equals("b")) yalign = FlexCell.BOTTOM;
        if (align.equals("x")) yalign = FlexCell.EXPANDY;
     }
     if (strTk.hasMoreTokens()) xext   = Integer.parseInt(strTk.nextToken());
     if (strTk.hasMoreTokens()) yext   = Integer.parseInt(strTk.nextToken());
     cells[x][y] = new FlexCell(xalign, yalign, xext, yext, comp);
  }
  //---------------------------------------------------------------------------
  public void removeLayoutComponent(Component comp)
  {
     for(int x=0; x<width; x++)
        for(int y=0; y<height; y++)
           if (cells[x][y].ruponent == comp)
           {
              cells[x][y] = null;
              return;
           }
  }
  //---------------------------------------------------------------------------
  public Dimension preferredLayoutSize(Container parent)
  {
     synchronized (parent.getTreeLock())
     {
        calcMaxWidthArray();
        calcMaxHeightArray();
        int maxW = 0;
        int maxH = 0;
        for(int x=0; x<width; x++)  maxW += xpref[x];
        for(int y=0; y<height; y++) maxH += ypref[y];
        Insets insets = parent.getInsets();
        return new Dimension(insets.left + insets.right  + maxW + (width-1)*xgap,
                             insets.top  + insets.bottom + maxH + (height-1)*ygap);
     }
  }
  //---------------------------------------------------------------------------
  public Dimension minimumLayoutSize(Container parent)
  {
     return preferredLayoutSize(parent);
  }
  //---------------------------------------------------------------------------
  public void layoutContainer(Container parent)
  {
     synchronized (parent.getTreeLock())
     {
        FlexCell cell;
        //--- maximun preferred Width & Height calculus for each column ---
        calcMaxWidthArray();
        calcMaxHeightArray();
        //---------------------------------------------------------------------
        //--- Layout Calculus
        //---------------------------------------------------------------------
        Insets i = parent.getInsets();
        int maxWidth  = parent.getSize().width - i.left - i.right - (width-1)*xgap;
        int maxHeight = parent.getSize().height- i.top  - i.bottom- (height-1)*ygap;
        //--- total space occupied by fixed columns (and rows) ---
        int fixedWidth  = 0;
        int fixedHeight = 0;
        //--- number of variable columns (and rows) ---
        int varXCount = 0;
        int varYCount = 0;
        //--- width of a variable column (or row) ---
        int varWidth  = 0;
        int varHeight = 0;
        //---------------------------------------------------------------------
        //---   Handle Columns
        //---------------------------------------------------------------------
        //--- calc totale space occupied by fixed columns ---
        for(int x=0; x<width; x++)
        {
           if (xflags[x] == USEPREFERRED) fixedWidth += xpref[x];
              else varXCount++;
        }
        //--- calc width of a generic variable column ---
        if (varXCount != 0)
        {
           varWidth = (maxWidth - fixedWidth) / varXCount;
           if (varWidth < 0) varWidth = 0;
        }
        //--- calc width for expandable columns ---
        for(int x=0; x<width; x++) if (xflags[x] == EXPAND) xpref[x] = varWidth;
        //---------------------------------------------------------------------
        //---   Handle Rows
        //---------------------------------------------------------------------
        //--- calc totale space occupied by fixed rows ---
        for(int y=0; y<height; y++)
        {
           if (yflags[y] == USEPREFERRED) fixedHeight += ypref[y];
              else varYCount++;
        }
        //--- calc height of a generic variable row ---
        if (varYCount != 0)
        {
           varHeight = (maxHeight - fixedHeight) / varYCount;
           if (varHeight < 0) varHeight = 0;
        }
        //--- calc width for expandable rows ---
        for(int y=0; y<height; y++) if (yflags[y] == EXPAND) ypref[y] = varHeight;
        //---------------------------------------------------------------------
        //---   Do Layout
        //---------------------------------------------------------------------
        int currentX = i.left;
        int currentY = i.top;
        int compX, compY, compW, compH;
        int cellW, cellH;
        int xc, yc;
        for(int y=0; y<height; y++)
        {
           currentX = i.left;
           for(int x=0; x<width; x++)
           {
              //--- calculate current cell width and height ---
              cellW = 0;
              cellH = 0;
              cell = cells[x][y];
              if (cell != null)
              {
                 for(xc = x; xc< x + cell.xext; xc++) cellW += xpref[xc];
                 for(yc = y; yc< y + cell.yext; yc++) cellH += ypref[yc];
                 Dimension compSize = cell.ruponent.getPreferredSize();
                 //------------------------------------------------------------
                 //--- calculate compX & compW depending on align
                 //------------------------------------------------------------
                 switch(cell.xalign)
                 {
                    case FlexCell.LEFT:
                             compX = currentX;
                             compW = compSize.width;
                             break;
                    case FlexCell.CENTERX:
                             compX = currentX + (cellW - compSize.width)/2;
                             compW = compSize.width;
                             break;
                    case FlexCell.RIGHT:
                             compX = currentX + cellW - compSize.width;
                             compW = compSize.width;
                             break;
                    case FlexCell.EXPANDX:
                             compX = currentX;
                             compW = cellW;
                             break;
                    default: System.out.println("FlexLayout: invalid X align type");
                             compX = currentX;
                             compW = cellW;
                             break;
                 }
                 //------------------------------------------------------------
                 //--- calculate compY & compH depending on align
                 //------------------------------------------------------------
                 switch(cell.yalign)
                 {
                    case FlexCell.TOP:
                             compY = currentY;
                             compH = compSize.height;
                             break;
                    case FlexCell.CENTERY:
                             compY = currentY + (cellH - compSize.height)/2;
                             compH = compSize.height;
                             break;
                    case FlexCell.BOTTOM:
                             compY = currentY + cellH - compSize.height;
                             compH = compSize.height;
                             break;
                    case FlexCell.EXPANDY:
                             compY = currentY;
                             compH = cellH;
                             break;
                    default: System.out.println("FlexLayout: invalid Y align type");
                             compY = currentY;
                             compH = cellH;
                            break;
                 }
                 //--- resize component ---
                 cell.ruponent.setBounds(compX, compY, compW + (cell.xext-1)*xgap,
                                                        compH + (cell.yext-1)*ygap);
              }
              currentX += xpref[x] + xgap;
           }
           currentY += ypref[y] + ygap;
        }
     }
  }
  //---------------------------------------------------------------------------
  private void calcMaxWidthArray()
  {
     //--- maximun preferred Width calculus for each column ---
     FlexCell cell;
     int maxPrefW, curPrefW;
     for(int x=0; x<width; x++)
     {
        maxPrefW = 0;
        for(int y=0; y<height; y++)
        {
           cell = cells[x][y];
           if (cell != null && cell.xext == 1)
           {
              curPrefW = cell.ruponent.getPreferredSize().width;
              if (curPrefW > maxPrefW) maxPrefW = curPrefW;
           }
        }
        if (maxPrefW == 0) maxPrefW = xnullgap;
        xpref[x] = maxPrefW;
     }
  }
  //---------------------------------------------------------------------------
  private void calcMaxHeightArray()
  {
     //--- maximun preferred Height calculus for each row ---
     FlexCell cell;
     int maxPrefH, curPrefH;
     for(int y=0; y<height; y++)
     {
        maxPrefH = 0;
        for(int x=0; x<width; x++)
        {
           cell = cells[x][y];
           if (cell != null && cell.yext == 1)
           {
              curPrefH = cell.ruponent.getPreferredSize().height;
              if (curPrefH > maxPrefH) maxPrefH = curPrefH;
           }
        }
        if (maxPrefH == 0) maxPrefH = ynullgap;
        ypref[y] = maxPrefH;
     }
  }

} class FlexCell {

  //--- X align constants ---
  public static final int LEFT    = 0;
  public static final int CENTERX = 1;
  public static final int RIGHT   = 2;
  public static final int EXPANDX = 3;
  //--- Y align constants ---
  public static final int TOP     = 0;
  public static final int CENTERY = 1;
  public static final int BOTTOM  = 2;
  public static final int EXPANDY = 3;
  public int xalign, xext;
  public int yalign, yext;
  public Component component;
  //---------------------------------------------------------------------------
  public FlexCell(int xalign, int yalign, int xext, int yext, Component c)
  {
     this.xalign = xalign;
     this.yalign = yalign;
     this.xext   = xext;
     this.yext   = yext;
     component   = c;
  }

}



 </source>
   
  
 
  



GraphPaperLayout

   <source lang="java">
   

/* From http://java.sun.ru/docs/books/tutorial/index.html */ /*

* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* -Redistribution of source code must retain the above copyright notice, this
*  list of conditions and the following disclaimer.
*
* -Redistribution 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.
*
* Neither the name of Sun Microsystems, Inc. or the names of contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* This software is provided "AS IS," without a warranty of any kind. ALL
* EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
* ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
* AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
* DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
* REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
* INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
* OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* You acknowledge that this software is not designed, licensed or intended
* for use in the design, construction, operation or maintenance of any
* nuclear facility.
*/

import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.LayoutManager2; import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Hashtable; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; public class GraphPaperTest extends JPanel {

 public GraphPaperTest() {
   setLayout(new GraphPaperLayout(new Dimension(5, 5)));
   // Add a 1x1 Rect at (0,0)
   add(new JButton("1"), new Rectangle(0, 0, 1, 1));
   // Add a 2x1 Rect at (2,0)
   add(new JButton("2"), new Rectangle(2, 0, 2, 1));
   // Add a 1x2 Rect at (1,1)
   add(new JButton("3"), new Rectangle(1, 1, 1, 2));
   // Add a 2x2 Rect at (3,2)
   add(new JButton("4"), new Rectangle(3, 2, 2, 2));
   // Add a 1x1 Rect at (0,4)
   add(new JButton("5"), new Rectangle(0, 4, 1, 1));
   // Add a 1x2 Rect at (2,3)
   add(new JButton("6"), new Rectangle(2, 3, 1, 2));
 }
 public static void main(String[] args) {
   JFrame f = new JFrame("GraphPaperTest");
   f.addWindowListener(new WindowAdapter() {
     public void windowClosing(WindowEvent e) {
       System.exit(0);
     }
   });
   f.getContentPane().add(new GraphPaperTest(), BorderLayout.CENTER);
   f.pack();
   f.setVisible(true);
 }

} /**

* The GraphPaperLayout class is a layout manager that lays out a
* container"s components in a rectangular grid, similar to GridLayout. Unlike
* GridLayout, however, components can take up multiple rows and/or columns. The
* layout manager acts as a sheet of graph paper. When a component is added to
* the layout manager, the location and relative size of the component are
* simply supplied by the constraints as a Rectangle.
*

*

 * 
 * import java.awt.*;
 * import java.applet.Applet;
 * 
 * public class ButtonGrid extends Applet {
 *   public void init() {
 *     setLayout(new GraphPaperLayout(new Dimension(5, 5)));
 *     // Add a 1x1 Rect at (0,0)
 *     add(new Button("1"), new Rectangle(0, 0, 1, 1));
 *     // Add a 2x1 Rect at (2,0)
 *     add(new Button("2"), new Rectangle(2, 0, 2, 1));
 *     // Add a 1x2 Rect at (1,1)
 *     add(new Button("3"), new Rectangle(1, 1, 1, 2));
 *     // Add a 2x2 Rect at (3,2)
 *     add(new Button("4"), new Rectangle(3, 2, 2, 2));
 *     // Add a 1x1 Rect at (0,4)
 *     add(new Button("5"), new Rectangle(0, 4, 1, 1));
 *     // Add a 1x2 Rect at (2,3)
 *     add(new Button("6"), new Rectangle(2, 3, 1, 2));
 *   }
 * }
 * 
* 
* @author Michael Martak
*/

class GraphPaperLayout implements LayoutManager2 {

 int hgap; //horizontal gap
 int vgap; //vertical gap
 Dimension gridSize; //grid size in logical units (n x m)
 Hashtable compTable; //constraints (Rectangles)
 /**
  * Creates a graph paper layout with a default of a 1 x 1 graph, with no
  * vertical or horizontal padding.
  */
 public GraphPaperLayout() {
   this(new Dimension(1, 1));
 }
 /**
  * Creates a graph paper layout with the given grid size, with no vertical
  * or horizontal padding.
  */
 public GraphPaperLayout(Dimension gridSize) {
   this(gridSize, 0, 0);
 }
 /**
  * Creates a graph paper layout with the given grid size and padding.
  * 
  * @param gridSize
  *            size of the graph paper in logical units (n x m)
  * @param hgap
  *            horizontal padding
  * @param vgap
  *            vertical padding
  */
 public GraphPaperLayout(Dimension gridSize, int hgap, int vgap) {
   if ((gridSize.width <= 0) || (gridSize.height <= 0)) {
     throw new IllegalArgumentException(
         "dimensions must be greater than zero");
   }
   this.gridSize = new Dimension(gridSize);
   this.hgap = hgap;
   this.vgap = vgap;
   compTable = new Hashtable();
 }
 /**
  * @return the size of the graph paper in logical units (n x m)
  */
 public Dimension getGridSize() {
   return new Dimension(gridSize);
 }
 /**
  * Set the size of the graph paper in logical units (n x m)
  */
 public void setGridSize(Dimension d) {
   setGridSize(d.width, d.height);
 }
 /**
  * Set the size of the graph paper in logical units (n x m)
  */
 public void setGridSize(int width, int height) {
   gridSize = new Dimension(width, height);
 }
 public void setConstraints(Component comp, Rectangle constraints) {
   compTable.put(comp, new Rectangle(constraints));
 }
 /**
  * Adds the specified component with the specified name to the layout. This
  * does nothing in GraphPaperLayout, since constraints are required.
  */
 public void addLayoutComponent(String name, Component comp) {
 }
 /**
  * Removes the specified component from the layout.
  * 
  * @param comp
  *            the component to be removed
  */
 public void removeLayoutComponent(Component comp) {
   compTable.remove(comp);
 }
 /**
  * Calculates the preferred size dimensions for the specified panel given
  * the components in the specified parent container.
  * 
  * @param parent
  *            the component to be laid out
  * 
  * @see #minimumLayoutSize
  */
 public Dimension preferredLayoutSize(Container parent) {
   return getLayoutSize(parent, true);
 }
 /**
  * Calculates the minimum size dimensions for the specified panel given the
  * components in the specified parent container.
  * 
  * @param parent
  *            the component to be laid out
  * @see #preferredLayoutSize
  */
 public Dimension minimumLayoutSize(Container parent) {
   return getLayoutSize(parent, false);
 }
 /**
  * Algorithm for calculating layout size (minimum or preferred).
  * <p>
  * The width of a graph paper layout is the largest cell width (calculated
  * in getLargestCellSize() times the number of columns, plus
  * the horizontal padding times the number of columns plus one, plus the
  * left and right insets of the target container.
  * <p>
  * The height of a graph paper layout is the largest cell height (calculated
  * in getLargestCellSize() times the number of rows, plus the
  * vertical padding times the number of rows plus one, plus the top and
  * bottom insets of the target container.
  * 
  * @param parent
  *            the container in which to do the layout.
  * @param isPreferred
  *            true for calculating preferred size, false for calculating
  *            minimum size.
  * @return the dimensions to lay out the subcomponents of the specified
  *         container.
  * @see java.awt.GraphPaperLayout#getLargestCellSize
  */
 protected Dimension getLayoutSize(Container parent, boolean isPreferred) {
   Dimension largestSize = getLargestCellSize(parent, isPreferred);
   Insets insets = parent.getInsets();
   largestSize.width = (largestSize.width * gridSize.width)
       + (hgap * (gridSize.width + 1)) + insets.left + insets.right;
   largestSize.height = (largestSize.height * gridSize.height)
       + (vgap * (gridSize.height + 1)) + insets.top + insets.bottom;
   return largestSize;
 }
 /**
  * Algorithm for calculating the largest minimum or preferred cell size.
  * <p>
  * Largest cell size is calculated by getting the applicable size of each
  * component and keeping the maximum value, dividing the component"s width
  * by the number of columns it is specified to occupy and dividing the
  * component"s height by the number of rows it is specified to occupy.
  * 
  * @param parent
  *            the container in which to do the layout.
  * @param isPreferred
  *            true for calculating preferred size, false for calculating
  *            minimum size.
  * @return the largest cell size required.
  */
 protected Dimension getLargestCellSize(Container parent, boolean isPreferred) {
   int ncomponents = parent.getComponentCount();
   Dimension maxCellSize = new Dimension(0, 0);
   for (int i = 0; i < ncomponents; i++) {
     Component c = parent.getComponent(i);
     Rectangle rect = (Rectangle) compTable.get(c);
     if (c != null && rect != null) {
       Dimension componentSize;
       if (isPreferred) {
         componentSize = c.getPreferredSize();
       } else {
         componentSize = c.getMinimumSize();
       }
       // Note: rect dimensions are already asserted to be > 0 when the
       // component is added with constraints
       maxCellSize.width = Math.max(maxCellSize.width,
           componentSize.width / rect.width);
       maxCellSize.height = Math.max(maxCellSize.height,
           componentSize.height / rect.height);
     }
   }
   return maxCellSize;
 }
 /**
  * Lays out the container in the specified container.
  * 
  * @param parent
  *            the component which needs to be laid out
  */
 public void layoutContainer(Container parent) {
   synchronized (parent.getTreeLock()) {
     Insets insets = parent.getInsets();
     int ncomponents = parent.getComponentCount();
     if (ncomponents == 0) {
       return;
     }
     // Total parent dimensions
     Dimension size = parent.getSize();
     int totalW = size.width - (insets.left + insets.right);
     int totalH = size.height - (insets.top + insets.bottom);
     // Cell dimensions, including padding
     int totalCellW = totalW / gridSize.width;
     int totalCellH = totalH / gridSize.height;
     // Cell dimensions, without padding
     int cellW = (totalW - ((gridSize.width + 1) * hgap))
         / gridSize.width;
     int cellH = (totalH - ((gridSize.height + 1) * vgap))
         / gridSize.height;
     for (int i = 0; i < ncomponents; i++) {
       Component c = parent.getComponent(i);
       Rectangle rect = (Rectangle) compTable.get(c);
       if (rect != null) {
         int x = insets.left + (totalCellW * rect.x) + hgap;
         int y = insets.top + (totalCellH * rect.y) + vgap;
         int w = (cellW * rect.width) - hgap;
         int h = (cellH * rect.height) - vgap;
         c.setBounds(x, y, w, h);
       }
     }
   }
 }
 // LayoutManager2 /////////////////////////////////////////////////////////
 /**
  * Adds the specified component to the layout, using the specified
  * constraint object.
  * 
  * @param comp
  *            the component to be added
  * @param constraints
  *            where/how the component is added to the layout.
  */
 public void addLayoutComponent(Component comp, Object constraints) {
   if (constraints instanceof Rectangle) {
     Rectangle rect = (Rectangle) constraints;
     if (rect.width <= 0 || rect.height <= 0) {
       throw new IllegalArgumentException(
           "cannot add to layout: rectangle must have positive width and height");
     }
     if (rect.x < 0 || rect.y < 0) {
       throw new IllegalArgumentException(
           "cannot add to layout: rectangle x and y must be >= 0");
     }
     setConstraints(comp, rect);
   } else if (constraints != null) {
     throw new IllegalArgumentException(
         "cannot add to layout: constraint must be a Rectangle");
   }
 }
 /**
  * Returns the maximum size of this component.
  * 
  * @see java.awt.ruponent#getMinimumSize()
  * @see java.awt.ruponent#getPreferredSize()
  * @see LayoutManager
  */
 public Dimension maximumLayoutSize(Container target) {
   return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
 }
 /**
  * Returns the alignment along the x axis. This specifies how the component
  * would like to be aligned relative to other components. The value should
  * be a number between 0 and 1 where 0 represents alignment along the
  * origin, 1 is aligned the furthest away from the origin, 0.5 is centered,
  * etc.
  */
 public float getLayoutAlignmentX(Container target) {
   return 0.5f;
 }
 /**
  * Returns the alignment along the y axis. This specifies how the component
  * would like to be aligned relative to other components. The value should
  * be a number between 0 and 1 where 0 represents alignment along the
  * origin, 1 is aligned the furthest away from the origin, 0.5 is centered,
  * etc.
  */
 public float getLayoutAlignmentY(Container target) {
   return 0.5f;
 }
 /**
  * Invalidates the layout, indicating that if the layout manager has cached
  * information it should be discarded.
  */
 public void invalidateLayout(Container target) {
   // Do nothing
 }

}



 </source>
   
  
 
  



Place components at exact locations (x, y, width, height) and then determine how they behave when the window containing them (their parent) is resized

   <source lang="java">
   

import java.awt.*; import java.util.*; /*

* @(#)FunLayout.java   1.0  96/10/12  Eric Swildens  Copyright (c) 1996
*
* Permission to use, copy, modify, and distribute this software
* for any purpose is hereby granted provided that this copyright
* notice appears in all copies.
*
* NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE ARE GIVEN, EITHER EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
*/

public class FunLayout implements LayoutManager { // Using this layout manager, you can place components at exact // locations (x, y, width, height) and then determine how they // behave when the window containing them (their parent) is resized. // // sample use: // // fun1.html: // // <title>fun1 example</title> // <applet code="fun1.class" width=400 height=300> </applet> // // fun1.java: // // import java.applet.Applet; // import java.awt.*; // // public class fun1 extends Applet // { // public void init() // { // FunLayout layout = new FunLayout(); // setLayout(layout); // // setBackground(Color.lightGray); // // Button rightButton1 = new Button("Button1"); // rightButton1.reshape(300, 5, 90, 20); // add(rightButton1); // layout.movesRight(rightButton1); // // Button rightButton2 = new Button("Button 2"); // rightButton2.reshape(200, 5, 90, 20); // add(rightButton2); // layout.movesRight(rightButton2); // // Panel midPanel = new Panel(); // midPanel.reshape(5, 40, 390, 200); // midPanel.setBackground(Color.blue); // layout.widthChanges(midPanel); // layout.heightChanges(midPanel); // add(midPanel); // // Panel statusBar = new Panel(); // statusBar.reshape(5, 245, 390, 20); // statusBar.setBackground(Color.black); // layout.movesDown(statusBar); // layout.widthChanges(statusBar); // add(statusBar); // } // } // // The above code creates an applet containing 2 buttons, a center panel // and a status panel. The two buttons are placed next to each other // in the upper right. When the window is sized wider, the buttons // will move to the right to stick near the edge of the window. // // The midPanel is placed in the center and when the window is sized // larger (in both dimensions), the panel will grow wider and taller. // // The statusBar is placed on the bottom and sticks to the bottom of // the panel when it is sized larger or smaller in height (it moves // down if the window it is contained in is sized to a larger height). // It will grow wider if the window it is contained in is sized wider. // // The advantage of the FunLayout is that you place components where you // want them to appear (best when using an interface builder) and still // have control over what happens during sizing. // // This is the default layout mechanism many interface systems use, such // as Netscape"s IFC. In fact, if you use this layout manager, you will // find porting your code to Netscape"s IFC much easier, as the layout // container here is very similar to Netscape"s IFC layout mechanism. // // There are only 4 methods which determine how components are resized // // layout.movesRight(comp); // layout.movesDown(comp); // layout.widthChanges(comp); // layout.heightChanges(comp); // // When you determine which to choose, you should ask "What should the // component do when the window is sized larger?" // // If you don"t call any of the above methods for a component, it will // simply stay at its current location. // // It"s more Fun than a Bag of layouts :-) // private Hashtable _moves; private Hashtable _negSized; private Dimension _prevContainerSize; private final static int MOVES_RIGHT = 2; private final static int MOVES_DOWN = 4; private final static int HEIGHT_CHANGES = 8; private final static int WIDTH_CHANGES = 16; public FunLayout()

 {
 _moves = new Hashtable();
 _negSized = new Hashtable();
 }

private int _getMove(Component comp)

 {
 if (!_moves.containsKey(comp))
   return 0;
 return ((Integer)_moves.get(comp)).intValue();
 }

// // private methods // private void _setMove(Component comp, int move)

 {
 if (_moves.containsKey(comp))
   {
   move |= ((Integer)_moves.get(comp)).intValue();
   _moves.remove(comp);
   }
 _moves.put(comp, new Integer(move));
 }

// // LayoutManager implementation // public void addLayoutComponent(String name, Component c)

 {
 }

/**

 * When the window containing the given component is stretched to a
 * larger height, the given component will grow taller (and shorter
 * when the window is shortened).
 * @param comp the target Component
 */

public void heightChanges(Component comp)

 {
 if ((_getMove(comp) & MOVES_DOWN) > 0)
   System.out.println(getClass() + ":layout conflict for " + comp);
 _setMove(comp, HEIGHT_CHANGES);
 }

public void layoutContainer(Container con)

 {
 int i, count, deltax, deltay, move;
 Dimension conSize;
 Rectangle rect;
 Component comp;
 conSize = con.getSize();
 if (_prevContainerSize == null)
   {
   _prevContainerSize = conSize;
   return;
   }
 deltax = conSize.width - _prevContainerSize.width;
 deltay = conSize.height - _prevContainerSize.height;
 _prevContainerSize = conSize;
 count = con.countComponents();
 for (i = 0; i < count; i++)
   {
   comp = con.getComponent(i);
   if (!comp.isVisible())
     continue;
   move = _getMove(comp);
   if (move == 0)
     continue;
   rect = comp.getBounds();
   if (_negSized.containsKey(comp))
     {
     // the component is really at a negative size
     rect = (Rectangle)_negSized.get(comp);
     _negSized.remove(comp);
     }
   if ((move & MOVES_RIGHT) > 0)
     rect.x += deltax;
   else if ((move & WIDTH_CHANGES) > 0)
     rect.width += deltax;
   if ((move & MOVES_DOWN) > 0)
     rect.y += deltay;
   else if ((move & HEIGHT_CHANGES) > 0)
     rect.height += deltay;
   // if a components size becomes negative, we track it since the AWT
   // does not allow components to have a size < (0, 0)
   if (rect.width < 0 || rect.height < 0)
     _negSized.put(comp, rect);
   comp.setBounds(rect.x, rect.y, rect.width, rect.height);
   }
 }

public Dimension minimumLayoutSize(Container target)

 {
 return new Dimension(10, 10);
 }

/**

 * When the window containing the given component is stretched to a
 * larger height, the given component will move down (and up
 * when the window is shortened).
 * @param comp the target Component
 */

public void movesDown(Component comp)

 {
 if ((_getMove(comp) & HEIGHT_CHANGES) > 0)
   System.out.println(getClass() + ":layout conflict for " + comp);
 _setMove(comp, MOVES_DOWN);
 }

// // public methods // /**

 * When the window containing the given component is widened, the
 * component will move right (and left when the window is shrunk).
 * @param comp the target Component
 */

public void movesRight(Component comp)

 {
 if ((_getMove(comp) & WIDTH_CHANGES) > 0)
   System.out.println(getClass() + ":layout conflict for " + comp);
 _setMove(comp, MOVES_RIGHT);
 }

public Dimension preferredLayoutSize(Container con)

 {
 Component comp;
 Rectangle rect;
 int i, count;
 Dimension d;
 d = new Dimension(0, 0);
 count = con.countComponents();
 for (i = 0; i < count; i++)
   {
   comp = con.getComponent(i);
   if (!comp.isVisible())
     continue;
   rect = comp.getBounds();
   if (d.width < rect.x + rect.width)
     d.width = rect.x + rect.width;
   if (d.height < rect.y + rect.height)
     d.height = rect.y + rect.height;
   }
 return d;
 }

public void removeLayoutComponent(Component c)

 {
 if (_negSized.containsKey(c))
   _negSized.remove(c);
 }

/**

 * When the window containing the given component is widened, the
 * component will grow wider (and smaller when the window is shrunk).
 * @param comp the target Component
 */

public void widthChanges(Component comp)

 {
 if ((_getMove(comp) & MOVES_RIGHT) > 0)
   System.out.println(getClass() + ":layout conflict for " + comp);
 _setMove(comp, WIDTH_CHANGES);
 }

}



 </source>
   
  
 
  



Relative Layout Manager for Java J2SE

   <source lang="java">
   

/*

* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 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.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import java.awt.Point; import java.util.StringTokenizer; import java.util.Vector; /**

* <p>
* RelativeLayout, a Relative Layout Manager for Java J2SE. Mainly for porting
* tired old code that uses x,y locations. You really can"t just assign x,y
* locations to components in Java Java J2SE - it breaks badly when the user
* resizes (and you can not mandate that the user can"t resize you --
* see any book on UI design for that little discussion -- and can
* also look bad due to resolution independance. Symantec Cafe 1.x, for example,
* used to spit out unfortunate (and unmaintainable) code like this:
* 
*
 * setLayout(null);
 * setSize(331, 241);
 * label1 = new Label("Info Applet", Label.CENTER);
 * add(label1);
 * label1.setBounds(91, 19, 107, 15);
 * 
* 
*

*

* Bleaarrgghh!!! To make it work properly at all resolutions and * survive user-initiated resize actions, change it to * *

 * 
 *   setLayout(new RelativeLayout(331,241,false);
 *   label1=new Label("Info Applet", Label.CENTER);
 *   add("91,19", label1);
 *  
 * 
* 
* Note that it"s actually less work to get it right. Symantec,
* Microsoft, and others, please take note!
*

* 
* @author Ian Darwin, http://www.darwinsys.ru/
*/

public class RelativeLayout implements LayoutManager {

 /** requested absolute width of canvas */
 protected int reqWid;
 /** requested absolute height of canvas */
 protected int reqHgt;
 /** actual size width when laid out */
 protected int curWid;
 /** actual size height when laid out */
 protected int curHgt;
 /** to track Components added by named add form. */
 protected Vector curComps = new Vector();
 /**
  * Constructs an RelativeLayout, given original hard-coded size of panel.
  */
 public RelativeLayout(int wid, int ht) {
   this.reqWid = wid;
   this.reqHgt = ht;
 }
 /**
  * Called by AWT when the user uses the form add(name, Component). Adds the
  * specified component with the specified name to the layout.
  * 
  * @param name
  *            String with location for component c Note: the
  *            "name" must contain x, y location, ie., 
* add("" + 320 + "," + 100, new Button("Quit"));
* or
* add("320,100", new Button("Quit").
* This adds the Button at x=320, y=100 when the Panel is at its * original full size. * @param c * Component to be added. */ public void addLayoutComponent(String name, Component c) { int x, y; StringTokenizer st = new StringTokenizer(name, ","); x = Integer.parseInt(st.nextToken()); y = Integer.parseInt(st.nextToken()); // System.out.println("Adding: Name " + name +"; obj " + c // + "; x " + x + "; y " + y); Tracker t = new Tracker(x, y, c); curComps.addElement(t); } /** * Called by AWT to lay out the components in the target Container at its * current size. * * @param target * Container whose components are to be laid out. */ public void layoutContainer(Container target) { Dimension targSize = target.getSize(); Insets ins = target.getInsets(); // System.out.println("layoutContainer: size " + targSize); curWid = targSize.width; curHgt = targSize.height; float widRatio = (float) curWid / (float) reqWid; float hgtRatio = (float) curHgt / (float) reqHgt; for (int i = 0; i < curComps.size(); i++) { int px, py, pw, ph; Tracker t = (Tracker) curComps.elementAt(i); Component tc = t.getComponent(); Dimension d = tc.getPreferredSize(); px = ins.right + (int) (t.getRequestedLoc().x * widRatio); py = ins.top + (int) (t.getRequestedLoc().y * hgtRatio); pw = d.width; ph = d.height; // System.out.println("layoutContainer["+i+"]: move " + // tc + " to " + px + ", " + py); tc.setBounds(px, py, pw, ph); } } /** * Called from AWT to calculate the minimum size dimensions for the target * panel given the components in it. But we use our own list of named * insertions, not the list of Components that the container keeps. * * @param target * Container to calculate for */ public Dimension minimumLayoutSize(Container target) { int minw = 0, minh = 0; for (int i = 0; i < curComps.size(); i++) { Tracker t = (Tracker) curComps.elementAt(i); Component tc = t.getComponent(); Dimension d = tc.getMinimumSize(); Point rl = t.getRequestedLoc(); minw = Math.max(minw, rl.x + d.width); minh = Math.max(minh, rl.y + d.height); // System.out.println("minLay, minw = " + minw // + "; minh = " + minh); } return new Dimension(minw, minw); } /** * Called by AWT to compute the preferred size for the target panel given * our list of the components that it contains. * * @param target * Container to calculate for */ public Dimension preferredLayoutSize(Container target) { int prefw = 0, prefh = 0; for (int i = 0; i < curComps.size(); i++) { Tracker t = (Tracker) curComps.elementAt(i); Component tc = t.getComponent(); Dimension d = tc.getMinimumSize(); Point rl = t.getRequestedLoc(); prefw = Math.max(prefw, rl.x + d.width); prefh = Math.max(prefh, rl.y + d.height); // System.out.println("prefLay, prefw = " + // prefw + "; prefh = " + prefh); } return new Dimension(prefw, prefh); } /** * Called by AWT to remove a given component from the layout. * * @param c * Component to be removed */ public void removeLayoutComponent(Component c) { curComps.removeElement(c); } /** * Tracker is a class used only by RelativeLayout, to track the original * "requested" (hard-coded) x,y locations of each Component. */ class Tracker { int absx, absy; Component theComp; /** Construct a tracker item given its location and Component. */ Tracker(int x, int y, Component c) { this.absx = x; this.absy = y; this.theComp = c; } /** Extract the location as a Point. */ public Point getRequestedLoc() { return new Point(absx, absy); } /** Extract the Component from this Tracker. */ public Component getComponent() { return theComp; } }

}



 </source>
   
  
 
  



Specialised layout manager for a grid of components.

   <source lang="java">
 

/*

* JCommon : a free general purpose class library for the Java(tm) platform
* 
*
* (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
* 
* Project Info:  http://www.jfree.org/jcommon/index.html
*
* This library is free software; you can redistribute it and/or modify it 
* under the terms of the GNU Lesser General Public License as published by 
* the Free Software Foundation; either version 2.1 of the License, or 
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but 
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
* USA.  
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
* in the United States and other countries.]
* 
* --------------
* LCBLayout.java
* --------------
* (C) Copyright 2000-2005, by Object Refinery Limited.
*
* Original Author:  David Gilbert (for Object Refinery Limited);
* Contributor(s):   -;
*
* $Id: LCBLayout.java,v 1.5 2005/11/16 15:58:40 taqua Exp $
*
* Changes (from 26-Oct-2001)
* --------------------------
* 26-Oct-2001 : Changed package to com.jrefinery.layout.* (DG);
* 10-Oct-2002 : Fixed errors reported by Checkstyle (DG);
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import java.io.Serializable; /**

* Specialised layout manager for a grid of components.
*
* @author David Gilbert
*/

public class LCBLayout implements LayoutManager, Serializable {

   /** For serialization. */
   private static final long serialVersionUID = -2531780832406163833L;
   
   /** A constant for the number of columns in the layout. */
   private static final int COLUMNS = 3;
   /** Tracks the column widths. */
   private int[] colWidth;
   /** Tracks the row heights. */
   private int[] rowHeight;
   /** The gap between each label and component. */
   private int labelGap;
   /** The gap between each component and button. */
   private int buttonGap;
   /** The gap between rows. */
   private int vGap;
   /**
    * Creates a new LCBLayout with the specified maximum number of rows.
    *
    * @param maxrows  the maximum number of rows.
    */
   public LCBLayout(final int maxrows) {
       this.labelGap = 10;
       this.buttonGap = 6;
       this.vGap = 2;
       this.colWidth = new int[COLUMNS];
       this.rowHeight = new int[maxrows];
   }
   /**
    * Returns the preferred size using this layout manager.
    *
    * @param parent  the parent.
    *
    * @return the preferred size using this layout manager.
   */
   public Dimension preferredLayoutSize(final Container parent) {
       synchronized (parent.getTreeLock()) {
           final Insets insets = parent.getInsets();
           final int ncomponents = parent.getComponentCount();
           final int nrows = ncomponents / COLUMNS;
           for (int c = 0; c < COLUMNS; c++) {
               for (int r = 0; r < nrows; r++) {
                   final Component component 
                       = parent.getComponent(r * COLUMNS + c);
                   final Dimension d = component.getPreferredSize();
                   if (this.colWidth[c] < d.width) {
                       this.colWidth[c] = d.width;
                   }
                   if (this.rowHeight[r] < d.height) {
                       this.rowHeight[r] = d.height;
                   }
               }
           }
           int totalHeight = this.vGap * (nrows - 1);
           for (int r = 0; r < nrows; r++) {
               totalHeight = totalHeight + this.rowHeight[r];
           }
           final int totalWidth = this.colWidth[0] + this.labelGap 
               + this.colWidth[1] + this.buttonGap + this.colWidth[2];
           return new Dimension(
               insets.left + insets.right + totalWidth + this.labelGap 
                   + this.buttonGap,
               insets.top + insets.bottom + totalHeight + this.vGap
           );
       }
   }
   /**
    * Returns the minimum size using this layout manager.
    *
    * @param parent  the parent.
    *
    * @return the minimum size using this layout manager.
    */
   public Dimension minimumLayoutSize(final Container parent) {
       synchronized (parent.getTreeLock()) {
           final Insets insets = parent.getInsets();
           final int ncomponents = parent.getComponentCount();
           final int nrows = ncomponents / COLUMNS;
           for (int c = 0; c < COLUMNS; c++) {
               for (int r = 0; r < nrows; r++) {
                   final Component component 
                       = parent.getComponent(r * COLUMNS + c);
                   final Dimension d = component.getMinimumSize();
                   if (this.colWidth[c] < d.width) {
                       this.colWidth[c] = d.width;
                   }
                   if (this.rowHeight[r] < d.height) {
                       this.rowHeight[r] = d.height;
                   }
               }
           }
           int totalHeight = this.vGap * (nrows - 1);
           for (int r = 0; r < nrows; r++) {
               totalHeight = totalHeight + this.rowHeight[r];
           }
           final int totalWidth = this.colWidth[0] + this.labelGap 
               + this.colWidth[1] + this.buttonGap + this.colWidth[2];
           return new Dimension(
               insets.left + insets.right + totalWidth + this.labelGap 
               + this.buttonGap,
               insets.top + insets.bottom + totalHeight + this.vGap
           );
       }
   }
   /**
    * Lays out the components.
    *
    * @param parent  the parent.
    */
   public void layoutContainer(final Container parent) {
       synchronized (parent.getTreeLock()) {
           final Insets insets = parent.getInsets();
           final int ncomponents = parent.getComponentCount();
           final int nrows = ncomponents / COLUMNS;
           for (int c = 0; c < COLUMNS; c++) {
               for (int r = 0; r < nrows; r++) {
                   final Component component 
                       = parent.getComponent(r * COLUMNS + c);
                   final Dimension d = component.getPreferredSize();
                   if (this.colWidth[c] < d.width) {
                       this.colWidth[c] = d.width;
                   }
                   if (this.rowHeight[r] < d.height) {
                       this.rowHeight[r] = d.height;
                   }
               }
           }
           int totalHeight = this.vGap * (nrows - 1);
           for (int r = 0; r < nrows; r++) {
               totalHeight = totalHeight + this.rowHeight[r];
           }
           final int totalWidth = this.colWidth[0] + this.colWidth[1] 
                                                   + this.colWidth[2];
           // adjust the width of the second column to use up all of parent
           final int available = parent.getWidth() - insets.left 
               - insets.right - this.labelGap - this.buttonGap;
           this.colWidth[1] = this.colWidth[1] + (available - totalWidth);
           // *** DO THE LAYOUT ***
           int x = insets.left;
           for (int c = 0; c < COLUMNS; c++) {
               int y = insets.top;
               for (int r = 0; r < nrows; r++) {
                   final int i = r * COLUMNS + c;
                   if (i < ncomponents) {
                       final Component component = parent.getComponent(i);
                       final Dimension d = component.getPreferredSize();
                       final int h = d.height;
                       final int adjust = (this.rowHeight[r] - h) / 2;
                       parent.getComponent(i).setBounds(x, y + adjust, 
                               this.colWidth[c], h);
                   }
                   y = y + this.rowHeight[r] + this.vGap;
               }
               x = x + this.colWidth[c];
               if (c == 0) {
                   x = x + this.labelGap;
               }
               if (c == 1) {
                   x = x + this.buttonGap;
               }
           }
       }
   }
   /**
    * Not used.
    *
    * @param comp  the component.
    */
   public void addLayoutComponent(final Component comp) {
       // not used
   }
   /**
    * Not used.
    *
    * @param comp  the component.
    */
   public void removeLayoutComponent(final Component comp) {
       // not used
   }
   /**
    * Not used.
    *
    * @param name  the component name.
    * @param comp  the component.
    */
   public void addLayoutComponent(final String name, final Component comp) {
       // not used
   }
   /**
    * Not used.
    *
    * @param name  the component name.
    * @param comp  the component.
    */
   public void removeLayoutComponent(final String name, final Component comp) {
       // not used
   }

}


 </source>
   
  
 
  



Special simple layout used in TabbedContainer

   <source lang="java">
 

/*

* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common
* Development and Distribution License("CDDL") (collectively, the
* "License"). You may not use this file except in compliance with the
* License. You can obtain a copy of the License at
* http://www.netbeans.org/cddl-gplv2.html
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
* specific language governing permissions and limitations under the
* License.  When distributing the software, include this License Header
* Notice in each file and include the License file at
* nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the GPL Version 2 section of the License file that
* accompanied this code. If applicable, add the following below the
* License Header, with the fields enclosed by brackets [] replaced by
* your own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Contributor(s):
*
* The Original Software is NetBeans. The Initial Developer of the Original
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
* Microsystems, Inc. All Rights Reserved.
*
* If you wish your version of this file to be governed by only the CDDL
* or only the GPL Version 2, indicate your decision by adding
* "[Contributor] elects to include this software in this distribution
* under the [CDDL or GPL Version 2] license." If you do not indicate a
* single choice of license, a recipient has the option to distribute
* your version of this file under either the CDDL, the GPL Version 2 or
* to extend the choice of license to its licensees as provided above.
* However, if you add GPL Version 2 code and therefore, elected the GPL
* Version 2 license, then the option applies only if the new code is
* made subject to such option by the copyright holder.
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import java.lang.ref.WeakReference; import javax.swing.JComponent; /**

* Special simple layout used in TabbedContainer. Shows component in the
* "stack", it means that only one component is visible at any time, others are
* always hidden "below" the visible one. Use method showComponent to select
* visible component.
*
* @author Dafe Simonek
*/

class StackLayout implements LayoutManager {

   // #100486 - hold visibleComp weakly, because removeLayoutComponent may not
   // be called and then visibleComp is not freed. See StackLayoutTest for details.
   /**
    * Holds currently visible component or null if no comp is visible
    */
   private WeakReference<Component> visibleComp = null;
   /**
    * Set the currently displayed component.  If passed null for the component,
    * all contained components will be made invisible (sliding windows do this)
    * @param c Component to show
    * @param parent Parent container
    */
   public void showComponent(Component c, Container parent) {
       Component comp = getVisibleComponent();
       if (comp != c) {
           if (!parent.isAncestorOf(c) && c != null) {
               parent.add(c);
           }
           synchronized (parent.getTreeLock()) {
               if (comp != null) {
                   comp.setVisible(false);
               }
               visibleComp = new WeakReference<Component>(c);
               if (c != null) {
                   c.setVisible(true);
               }
   // trigger re-layout
   if (c instanceof JComponent) {
       ((JComponent)c).revalidate();
   }
   else {
       parent.validate(); //XXX revalidate should work!
   }
           }
       }
   }
   
   /** Allows support for content policies 
    * @return Currently visible component or null
    */
   public Component getVisibleComponent() {
       return visibleComp == null ? null : visibleComp.get();
   }
   /**
    * ********** Implementation of LayoutManager interface *********
    */
   public void addLayoutComponent(String name, Component comp) {
       synchronized (comp.getTreeLock()) {
           comp.setVisible(false);
           // keep consistency if showComponent was already called on this
           // component before
           if (comp == getVisibleComponent()) {
               visibleComp = null;
           }

/*System.out.println("Border dump for " + comp.getName()); borderDump((javax.swing.JComponent)comp, "");*/

       }
   }
   

/*private void borderDump (javax.swing.JComponent comp, String space) {

   javax.swing.border.Border compBorder = comp.getBorder();
   if (compBorder == null) {
       System.out.println(space + comp.getClass().getName() + " has no border.");
   } else {
       System.out.println(space + comp.getClass().getName() + ": " + compBorder.getClass().getName());
   }
   Component curComp;
   for (int i = 0; i < comp.getComponentCount(); i++) {
       curComp = comp.getComponent(i);
       if (curComp instanceof javax.swing.JComponent) {
           borderDump((javax.swing.JComponent)curComp, space + " ");
       }
   }

}*/

   public void removeLayoutComponent(Component comp) {
       synchronized (comp.getTreeLock()) {
           if (comp == getVisibleComponent()) {
               visibleComp = null;
           }
           // kick out removed component as visible, so that others
           // don"t have problems with hidden components
           comp.setVisible(true);
       }
   }
   public void layoutContainer(Container parent) {
       Component visibleComp = getVisibleComponent();
       if (visibleComp != null) {
           synchronized (parent.getTreeLock()) {
               Insets insets = parent.getInsets();
               visibleComp.setBounds(insets.left, insets.top, parent.getWidth()
                  - (insets.left + insets.right), parent.getHeight()
                  - (insets.top + insets.bottom));
           }
       }
   }
   public Dimension minimumLayoutSize(Container parent) {
       return getEmptySize();
   }
   public Dimension preferredLayoutSize(Container parent) {
       return getEmptySize();
   }
   /**
    * Specifies default size of empty container
    */
   private static Dimension getEmptySize() {
       return new Dimension(50, 50);
   }

}


 </source>
   
  
 
  



Square Layout

   <source lang="java">
   

/**

* The utillib library.
* More information is available at http://www.jinchess.ru/.
* Copyright (C) 2002 Alexander Maryanovsky.
* All rights reserved.
*
* The utillib library is free software; you can redistribute
* it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* The utillib library is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with utillib library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

import java.awt.*;

/**

* A LayoutManager which lays out a single component making sure its height is
* always the same as its width. If the parent container"s width differs from
* it height, the child will be laid out according to its x and y alignment.
*/

public class SquareLayout implements LayoutManager{


 /**
  * Creates a new SquareLayout.
  */
 public SquareLayout(){
 }
 
 
 
 /**
  * Creates a new Container with SquareLayout which will contain the specified
  * component.
  */
  
 public static Container createSquareContainer(Component child){
   Container container = new Container();
   container.setLayout(new SquareLayout());
   container.add(child);
   
   return container;
 }
 /**
  * Adds the specified component with the specified name to the layout. 
  */
 public void addLayoutComponent(String name, Component component){
   
 }
 
 
 /**
  * Removes the specified component from the layout. 
  */
 public void removeLayoutComponent(Component component){
   
 }
 
 
 
 /**
  * Returns the sole child of the specified container, or null if
  * none. Throws an IllegalStateException if there is more than
  * one child.
  */
  
 private Component getChild(Container c){
   int childCount = c.getComponentCount();
   if (childCount > 1)
     throw new IllegalStateException("May not layout more than one component");
   else if (childCount == 0)
     return null;
   else
     return c.getComponent(childCount - 1);
 }
 /**
  * Lays out the container in the specified panel. 
  */
 public void layoutContainer(Container container){
   Component child = getChild(container);
   if (child == null)
     return;
   
   Dimension parentSize = container.getSize();
   Insets insets = container.getInsets();
   
   // A rectangle specifying the actual area available for layout. 
   Rectangle rect = new Rectangle(insets.left, insets.top,
     parentSize.width - insets.left - insets.right, parentSize.height - insets.top - insets.bottom);
   int minSize = rect.width < rect.height ? rect.width : rect.height;
   int widthSpace = rect.width - minSize;
   int heightSpace = rect.height - minSize;
   child.setBounds(rect.x + (int)(widthSpace*child.getAlignmentX()),
                   rect.y + (int)(heightSpace*child.getAlignmentY()), minSize, minSize);
 }
 
 /**
  * Calculates the minimum size dimensions for the specified panel given the 
  * components in the specified parent container. 
  */
 public Dimension minimumLayoutSize(Container container){
   Component child = getChild(container);
   if (child == null)
     return new Dimension(0, 0);
   
   Dimension childMinSize = child.getMinimumSize();
   Insets insets = container.getInsets();
   
   int width = childMinSize.width + insets.left + insets.right;
   int height = childMinSize.height + insets.top + insets.bottom;
   int maxSize = Math.max(width, height);
   return new Dimension(maxSize, maxSize);
 }


 /**
  * Calculates the preferred size dimensions for the specified panel given the
  * components in the specified parent container. 
  */
 public Dimension preferredLayoutSize(Container container){
   Component child = getChild(container);
   if (child == null)
     return new Dimension(0, 0);
   
   Dimension childPrefSize = child.getPreferredSize();
   Insets insets = container.getInsets();
   
   int width = childPrefSize.width + insets.left + insets.right;
   int height = childPrefSize.height + insets.top + insets.bottom;
   int maxSize = Math.max(width, height);
   return new Dimension(maxSize, maxSize);
 }


}



 </source>
   
  
 
  



Stack Layout, uses an orientation to determine if the contents should be arranged horizontally or vertically.

   <source lang="java">
 

/*

*  StackLayout.java
*  2005-07-15
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager; import javax.swing.JSeparator; import javax.swing.JToolBar; import javax.swing.SwingConstants;

/**

* Similar to BoxLayout, uses an orientation to determine if the contents
* should be arranged horizontally or vertically.  By default, Resizes each
* item to equal width or height (depending on the orientation) based on the
* maximum preferred width or height of all items.
* @author Christopher Bach
*/

public class StackLayout implements LayoutManager {

 public static final int   HORIZONTAL = SwingConstants.HORIZONTAL;
 public static final int   VERTICAL = SwingConstants.VERTICAL;
 private int     ourOrientation = HORIZONTAL;
 private int     ourSpacing = 0;
 private boolean   ourDepthsMatched = true;
 private boolean   ourLengthsMatched = false;
 private boolean   ourFill = false;
 private boolean   ourDrop = false;
 private int     ourSqueezeFactor = 100;


 /**
  * Creates a new StackLayout with a horizontal orientation.
  */
 public StackLayout()
 {
 }
 /**
  * Creates a new StackLayout with the specified orientation.
  */
 public StackLayout(int orientation)
 {
   setOrientation(orientation);
 }
 /**
  * Creates a new StackLayout with the specified orientation and spacing.
  */
 public StackLayout(int orientation, int spacing)
 {
   setOrientation(orientation);
   setSpacing(spacing);
 }
 /**
  * Creates a new StackLayout matching the component lengths and
  * depths as indicated.
  */
 public StackLayout(boolean matchLengths, boolean matchDepths)
 {
   setMatchesComponentLengths(matchLengths);
   setMatchesComponentDepths(matchDepths);
 }
 /**
  * Creates a new StackLayout with the specified orientation
  * and spacing, matching the component lengths and depths
  * as indicated.
  */
 public StackLayout(int orientation, int spacing,
         boolean matchLengths, boolean matchDepths)
 {
   setOrientation(orientation);
   setSpacing(spacing);
   setMatchesComponentLengths(matchLengths);
   setMatchesComponentDepths(matchDepths);
 }




 /**
  * Sets this StackLayout"s orientation, either
  * SwingConstants.HORIZONTAL or SwingConstants.VERTICAL.
  */
 public void setOrientation(int orientation)
 {
   if (orientation == HORIZONTAL || orientation == VERTICAL)
   {
     ourOrientation = orientation;
   }
 }
 /**
  * Returns this StackLayout"s orientation, either
  * SwingConstants.HORIZONTAL or SwingConstants.VERTICAL.
  */
 public int getOrientation()
 {
   return ourOrientation;
 }
 /**
  * Sets the spacing between components that this StackLayout uses
  * when laying out the components.
  */
 public void setSpacing(int spacing)
 {
   ourSpacing = Math.max(0, spacing);
 }
 /**
  * Returns the spacing between components that this StackLayout uses
  * when laying out the components.
  */
 public int getSpacing()
 {
   return ourSpacing;
 }
 /**
  * Sets whether or not the last component in the stack
  * should be stretched to fill any remaining space within
  * the parent container.  The default value is false.
  */
 public void setFillsTrailingSpace(boolean shouldFill)
 {
   ourFill = shouldFill;
 }
 /**
  * Returns whether or not the last component in the stack
  * should be stretched to fill any remaining space within
  * the parent container.
  */
 public boolean fillsTrailingSpace()
 {
   return ourFill;
 }
 /**
  * Sets whether or not components in the stack that do not
  * fit in the parent container should be left out of the layout.
  * The default value is false;
  */
 public void setDropsPartialComponents(boolean shouldDrop)
 {
   ourDrop = shouldDrop;
 }
 /**
  * Returns whether or not components in the stack that do not
  * fit in the parent container should be left out of the layout.
  */
 public boolean dropsPartialComponents()
 {
   return ourDrop;
 }
 /**
  * Sets whether or not all components in the stack will be sized
  * to the same height (when in a horizontal orientation) or width
  * (when in a vertical orientation).  The default value is true.
  */
 public void setMatchesComponentDepths(boolean match)
 {
   ourDepthsMatched = match;
 }
 /**
  * Returns whether or not all components in the stack will be sized
  * to the same height (when in a horizontal orientation) or width
  * (when in a vertical orientation).
  */
 public boolean matchesComponentDepths()
 {
   return ourDepthsMatched;
 }
 /**
  * Sets whether or not all components in the stack will be sized
  * to the same width (when in a horizontal orientation) or height
  * (when in a vertical orientation).  The default value is false.
  */
 public void setMatchesComponentLengths(boolean match)
 {
   ourLengthsMatched = match;
 }
 /**
  * Returns whether or not all components in the stack will be sized
  * to the same width (when in a horizontal orientation) or height
  * (when in a vertical orientation).
  */
 public boolean matchesComponentLengths()
 {
   return ourLengthsMatched;
 }
 /**
  * Sets the percentage of a component"s preferred size that it
  * may be squeezed in order to attempt to fit all components
  * into the layout.  The squeeze factor will only be applied
  * when this layout is set to match component lengths.
  *
  * For example, if the parent container is 100 pixels wide
  * and holds two buttons, the largest having a preferred
  * width of 80 pixels, a squeeze factor of 50 will allow each
  * button to be sized to as small as 40 pixels wide (50 percent
  * of the preferred width.
  *
  * The default value is 100.
  */
 public void setSqueezeFactor(int factor)
 {
   if (factor < 0) ourSqueezeFactor = 0;
   else if (factor > 100) ourSqueezeFactor = 100;
   else ourSqueezeFactor = factor;
 }
 /**
  * Returns the percentage of a component"s preferred size that it
  * may be squeezed in order to attempt to fit all components
  * into the layout.
  */
 public int getSqueezeFactor()
 {
   return ourSqueezeFactor;
 }






 ////// LayoutManager implementation //////
 /**
  * Adds the specified component with the specified name to this layout.
  */
 public void addLayoutComponent(String name, Component comp)
 {
 }
 /**
  * Removes the specified component from this layout.
  */
 public void removeLayoutComponent(Component comp)
 {
 }
 /**
  * Returns the preferred size for this layout to arrange the
  * indicated parent"s children.
  */
 public Dimension preferredLayoutSize(Container parent)
 {
   if (parent instanceof JToolBar)
   {
     setOrientation( ((JToolBar)parent).getOrientation() );
   }
   return preferredLayoutSize(parent, ourOrientation);
 }
 /**
  * Returns the preferred size for this layout to arrange the
  * indicated parent"s children at the specified orientation.
  */
 // public, because it"s useful - not one of the LayoutManager methods
 public Dimension preferredLayoutSize(Container parent, int orientation)
 {
   synchronized (parent.getTreeLock())
   {
     Component[] comps = parent.getComponents();
     Dimension total = new Dimension(0, 0);
     int depth = calculatePreferredDepth(comps, orientation);
     int length = ( ourLengthsMatched ?
       calculateAdjustedLength(comps, orientation, ourSpacing)
         : calculatePreferredLength(comps, orientation, ourSpacing) );
     total.width = (orientation == HORIZONTAL ? length : depth);
     total.height = (orientation == HORIZONTAL ? depth : length);
     Insets in = parent.getInsets();
     total.width += in.left + in.right;
     total.height += in.top + in.bottom;
     return total;
   }
   }


 /**
  * Returns the minimum size for this layout to arrange the
  * indicated parent"s children at the specified orientation.
  */
   public Dimension minimumLayoutSize(Container parent)
   {
   synchronized (parent.getTreeLock())
   {
     if (parent instanceof JToolBar)
     {
       setOrientation( ((JToolBar)parent).getOrientation() );
     }
     Component[] comps = parent.getComponents();
     Dimension total = new Dimension(0, 0);
     int depth = calculatePreferredDepth(comps, ourOrientation);
     int length = calculateMinimumLength(comps, ourOrientation, ourSpacing);
     total.width = (ourOrientation == HORIZONTAL ? length : depth);
     total.height = (ourOrientation == HORIZONTAL ? depth : length);
     Insets in = parent.getInsets();
     total.width += in.left + in.right;
     total.height += in.top + in.bottom;
     return total;
   }
   }


 /**
  * Lays out the child components within the indicated parent container.
  */
   public void layoutContainer(Container parent)
   {
   synchronized (parent.getTreeLock())
   {
     if (parent instanceof JToolBar)
     {
       setOrientation( ((JToolBar)parent).getOrientation() );
     }
     layoutComponents(parent);
   }
 }


 private void layoutComponents(Container parent)
 {
   Component[] components = parent.getComponents();
   Insets in = parent.getInsets();
   int maxHeight = parent.getHeight() - in.top - in.bottom;
   int maxWidth = parent.getWidth() - in.left - in.right;
   boolean horiz = (ourOrientation == HORIZONTAL);
   int totalDepth = calculatePreferredDepth(components, ourOrientation);
   totalDepth = Math.max( totalDepth, (horiz ? maxHeight : maxWidth) );
   int prefLength = ( ourLengthsMatched ?
             calculateAdjustedLength(components, ourOrientation, ourSpacing)
             : calculatePreferredLength(components, ourOrientation, ourSpacing) );
   int totalLength = Math.min( prefLength, (horiz ? maxWidth : maxHeight) );
   int a = (horiz ? in.left : in.top);
   int b = (horiz ? in.top : in.left);
   int l = 0, d = 0, sum = 0;
   int matchedLength = 0;
   Dimension prefsize = null;
   if (ourLengthsMatched)
   {
     matchedLength = ( horiz ? getMaxPrefWidth(components)
                   : getMaxPrefHeight(components) );
     if (prefLength > totalLength && ourSqueezeFactor < 100)
     {
       int minLength = calculateMinimumLength(components,
                     ourOrientation, ourSpacing);
       if (minLength >= totalLength)
       {
         matchedLength = (matchedLength * ourSqueezeFactor) / 100;
       }
       else
       {
         int numSeparators = countSeparators(components);
         int numComponents = components.length - numSeparators;
         int diff = (prefLength - totalLength) / numComponents;
         if ((prefLength - totalLength) % numComponents > 0) diff++;
         matchedLength -= diff;
       }
     }
   }
   for (int i=0; i < components.length; i++)
   {
     prefsize = components[i].getPreferredSize();
     if (!ourLengthsMatched) l = (horiz ? prefsize.width : prefsize.height);
     else l = matchedLength;
     if (components[i] instanceof JSeparator)
     {
       // l = Math.min(prefsize.width, prefsize.height);
       l = (horiz ? prefsize.width : prefsize.height);
       d = totalDepth;
       sum += l;
       if (ourDrop && sum > totalLength) l = 0;
     }
     else
     {
       sum += l;
       if (ourDrop && sum > totalLength) l = 0;
       else if (ourFill && !ourLengthsMatched && i == components.length - 1)
       {
         l = Math.max( l, (horiz ? maxWidth : maxHeight) );
       }
       if (ourDepthsMatched) d = totalDepth;
       else d = (horiz ? prefsize.height : prefsize.width);
     }
     if (horiz) components[i].setBounds(a, b + (totalDepth - d) / 2, l, d);
     else components[i].setBounds(b + (totalDepth - d) / 2, a, d, l);
     a += l + ourSpacing;
     sum += ourSpacing;
   }
 }






 /**
  * Returns the largest preferred width of the provided components.
  */
 private int getMaxPrefWidth(Component[] components)
 {
   int maxWidth = 0;
   int componentWidth = 0;
   Dimension d = null;
   for (int i=0; i < components.length; i++)
   {
     d = components[i].getPreferredSize();
     componentWidth = d.width;
     if (components[i] instanceof JSeparator)
     {
       componentWidth = Math.min(d.width, d.height);
     }
     maxWidth = Math.max(maxWidth, componentWidth);
   }
   return maxWidth;
 }
 /**
  * Returns the largest preferred height of the provided components.
  */
 private int getMaxPrefHeight(Component[] components)
 {
   int maxHeight = 0;
   int componentHeight = 0;
   Dimension d = null;
   for (int i=0; i < components.length; i++)
   {
     d = components[i].getPreferredSize();
     componentHeight = d.height;
     if (components[i] instanceof JSeparator)
     {
       componentHeight = Math.min(d.width, d.height);
     }
     else maxHeight = Math.max(maxHeight, componentHeight);
   }
   return maxHeight;
 }





 /**
  * Calculates the preferred "length" of this layout for the provided
  * components based on the largest component preferred size.
  */
 private int calculateAdjustedLength(Component[] components,
                   int orientation, int spacing)
 {
   int total = 0;
   int componentLength = ( orientation == HORIZONTAL ?
       getMaxPrefWidth(components) : getMaxPrefHeight(components) );
   for (int i=0; i < components.length; i++)
   {
     if (components[i] instanceof JSeparator)
     {
       Dimension d = components[i].getPreferredSize();
       // total += Math.min(d.width, d.height);
       total += (orientation == HORIZONTAL ? d.width : d.height);
     }
     else total += componentLength;
   }
   int gaps = Math.max(0, spacing * (components.length - 1));
   total += gaps;
   return total;
 }


 /**
  * Calculates the minimum "length" of this layout for the provided
  * components, taking the squeeze factor into account when necessary.
  */
 private int calculateMinimumLength(Component[] components,
                   int orientation, int spacing)
 {
   if (!ourLengthsMatched)  return calculatePreferredLength(
                     components, orientation, spacing );
   if (ourSqueezeFactor == 100)  return calculateAdjustedLength(
                     components, orientation, spacing);
   int total = 0;
   int componentLength = ( orientation == HORIZONTAL ?
       getMaxPrefWidth(components) : getMaxPrefHeight(components) );
   componentLength = (componentLength * ourSqueezeFactor) / 100;
   for (int i=0; i < components.length; i++)
   {
     if (components[i] instanceof JSeparator)
     {
       Dimension d = components[i].getPreferredSize();
       // total += Math.min(d.width, d.height);
       total += (orientation == HORIZONTAL ? d.width : d.height);
     }
     else total += componentLength;
   }
   int gaps = Math.max(0, spacing * (components.length - 1));
   total += gaps;
   return total;
 }


 /**
  * Calculates the preferred "length" of this layout for the provided
  * components.
  */
 private int calculatePreferredLength(Component[] components,
                   int orientation, int spacing)
 {
   int total = 0;
   Dimension d = null;
   for (int i=0; i < components.length; i++)
   {
     d = components[i].getPreferredSize();

// if (components[i] instanceof JSeparator) // { // total += Math.min(d.width, d.height); // } // // else

       total += (orientation == HORIZONTAL ? d.width : d.height);
   }
   int gaps = Math.max(0, spacing * (components.length - 1));
   total += gaps;
   return total;
 }


 /**
  * Returns the preferred "depth" of this layout for the provided
  * components.
  */
 private int calculatePreferredDepth(Component[] components, int orientation)
 {
   if (orientation == HORIZONTAL) return getMaxPrefHeight(components);
   else if (orientation == VERTICAL) return getMaxPrefWidth(components);
   else return 0;
 }
 private int countSeparators(Component[] components)
 {
   int count = 0;
   for (int i=0; i < components.length; i++)
   {
     if (components[i] instanceof JSeparator) count++;
   }
   return count;
 }

}


 </source>
   
  
 
  



Table Layout

   <source lang="java">
   

/**

* The utillib library.
* More information is available at http://www.jinchess.ru/.
* Copyright (C) 2002, 2003 Alexander Maryanovsky.
* All rights reserved.
*
* The utillib library is free software; you can redistribute
* it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* The utillib library is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with utillib library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager2; import java.util.Enumeration; import java.util.Hashtable; import java.util.NoSuchElementException; import java.util.Vector;

/**

* A LayoutManager which lays out the components in a table-like structure.
* Unlike GridLayout, the sizes of the rows and columns
* are dynamic, although properly aligned. The cell sizes are determined
* according to the preferred sizes of the components and each component is
* sized to either its maximum size or the cell size. Components are positioned
* within their cells according to their X and Y alignments.
* When a new component is added, it is placed in the first empty cell, in
* lexigraphic order. A new row is created if necessary.
* To create an empty cell, simply add blank component.
*/

public class TableLayout implements LayoutManager2{

 /**
  * The amount of columns in the table.
  */
 private final int columnCount;
 /**
  * The gap between columns, in pixels.
  */
 private final int xGap;
 /**
  * The gap between rows, in pixels.
  */
 private final int yGap;
 /**
  * A Vector of rows where each row is a Component array holding the components
  * in that row.
  */
 private final Vector rows = new Vector();
 /**
  * Creates a new TableLayout with the specified amount of columns,
  * horizontal/vertical gaps between columns/cells.
  */
 public TableLayout(int columnCount, int xGap, int yGap){
   if (columnCount <= 0)
     throw new IllegalArgumentException("The amount of columns must be positive");
   if (xGap < 0)
     throw new IllegalArgumentException("The horizontal gap may not be negative: "+xGap);
   if (yGap < 0)
     throw new IllegalArgumentException("The vertical gap may not be negative: "+yGap);
   this.columnCount = columnCount;
   this.xGap = xGap;
   this.yGap = yGap;
 }
 /**
  * Creates a new TableLayout with the specified amount of columns.
  */
 public TableLayout(int columnCount){
   this(columnCount, 0, 0);
 }


 /**
  * Adds the specified component to the layout.
  */
 public void addLayoutComponent(Component component, Object constraints){
   synchronized(component.getTreeLock()){
     int rowCount = rows.size();
     for (int i = 0; i < rowCount; i++){
       Component [] row = (Component [])rows.elementAt(i);
       for (int j = 0; j < row.length; j++){
         if (row[j] == null){
           row[j] = component;
           return;
         }
       }
     }
     Component [] newRow = new Component[columnCount];
     newRow[0] = component;
     rows.addElement(newRow);
   }
 }
 /**
  * Throws an exception.
  */
 public void addLayoutComponent(String name, Component component){
   throw new UnsupportedOperationException("deprecated addLayoutComponent(String, Component)");
 }


 /**
  * Removes the specified component from the layout.
  */
 public void removeLayoutComponent(Component component){
   synchronized(component.getTreeLock()){
     int rowCount = rows.size();
     outer: for (int i = 0; i < rowCount; i++){
       Component [] row = (Component [])rows.elementAt(i);
       for (int j = 0; j < row.length; j++){
         if (row[j] == component){
           row[j] = null;
           break outer;
         }
       }
     }
     // Remove any empty rows at the end.
     for (int i = rowCount - 1; i >= 0; i--){
       Component [] row = (Component [])rows.elementAt(i);
       boolean isEmpty = true;
       for (int j = 0; j < row.length; j++){
         if (row[j] != null){
           isEmpty = false;
           break;
         }
       }
       if (isEmpty)
         rows.removeElementAt(i);
       else
         break;
     }
   }
 }


 /**
  * Returns a matrix of Dimension objects specifying the preferred sizes of the
  * components we are going to layout.
  */
 private Dimension [][] getPreferredSizes(Container parent){
   int rowCount = rows.size();
   Dimension [][] prefSizes = new Dimension[rowCount][columnCount];
   for (int i = 0; i < rowCount; i++){
     Component [] row = (Component [])rows.elementAt(i);
     for (int j = 0; j < columnCount; j++){
       Component component = row[j];
       // Can only happen on the last line when all the remaining components are null as well
       if (component == null) 
         break;
       if (component.getParent() != parent)
         throw new IllegalStateException("Bad parent specified");
       prefSizes[i][j] = component.getPreferredSize();
     }
   }
   return prefSizes;
 }
 /**
  * Calculates and returns a Pair where the first object is an array holding
  * the column widths of our layout and the second is the rowHeights.
  */
 private Pair calculateLayout(Dimension [][] prefSizes){
   int rowCount = rows.size();
   int [] columnWidths = new int[columnCount];
   int [] rowHeights = new int[rowCount];
   // Find the maximum preferred row heights and column widths.
   for (int i = 0; i < rowCount; i++){
     for (int j = 0; j < columnCount; j++){
       Dimension prefSize = prefSizes[i][j];
       // Can only happen on the last line when all the remaining components are null as well
       if (prefSize == null)
         break;
       columnWidths[j] = Math.max(columnWidths[j], prefSize.width);
       rowHeights[i] = Math.max(rowHeights[i], prefSize.height);
     }
   }
   return new Pair(columnWidths, rowHeights);
 }


 /**
  * Lays out the specified container. Throws an
  * IllegalStateException if any of the components added via the
  * addLayoutComponent method have a different parent than the
  * specified Container.
  */
 public void layoutContainer(Container parent){
   synchronized(parent.getTreeLock()){
     int rowCount = rows.size();
     Insets parentInsets = parent.getInsets();
     // Collect the preferred sizes.
     Dimension [][] prefSizes = getPreferredSizes(parent);
     Pair layout = calculateLayout(prefSizes);
     int [] columnWidths = (int [])layout.getFirst();
     int [] rowHeights = (int [])layout.getSecond();
     Dimension prefParentSize = calculatePreferredLayoutSize(parent, columnWidths, rowHeights);
     Dimension parentSize = parent.getSize();
     Dimension layoutSize = 
       new Dimension(parentSize.width - xGap*(rowCount - 1) - parentInsets.left - parentInsets.right,
                     parentSize.height - yGap*(columnCount - 1) - parentInsets.top - parentInsets.bottom);
     Dimension prefLayoutSize =
       new Dimension(prefParentSize.width - xGap*(rowCount - 1) - parentInsets.left - parentInsets.right,
                     prefParentSize.height - yGap*(columnCount - 1) - parentInsets.top - parentInsets.bottom);
     // Layout the components.
     int y = parentInsets.top;
     for (int i = 0; i < rowCount; i++){
       int x = parentInsets.left;
       int cellHeight = (rowHeights[i]*layoutSize.height)/prefLayoutSize.height;
       Component [] row = (Component [])rows.elementAt(i);
       for (int j = 0; j < row.length; j++){
         int cellWidth = (columnWidths[j]*layoutSize.width)/prefLayoutSize.width;
         Component component = row[j];
         // Can only happen on the last line when all the remaining components are null as well
         if (component == null)
           break;
         Dimension maxSize = component.getMaximumSize();
         int compWidth = Math.min(maxSize.width, cellWidth);
         int compHeight = Math.min(maxSize.height, cellHeight);
         int compX = x + (int)((cellWidth - compWidth)*component.getAlignmentX());
         int compY = y + (int)((cellHeight - compHeight)*component.getAlignmentY());
         component.setBounds(compX, compY, compWidth, compHeight);
         x += cellWidth + xGap;
       }
       y += cellHeight + yGap;
     }
   }
 }
 /**
  * We"re not caching anything yet, so this call is ignored.
  */
 public void invalidateLayout(Container parent){
 }
 /**
  * Returns the preferred layout for the specified parent container.
  */
 public Dimension preferredLayoutSize(Container parent){
   synchronized(parent.getTreeLock()){
     Dimension [][] prefSizes = getPreferredSizes(parent);
     Pair layout = calculateLayout(prefSizes);
     int [] columnWidths = (int [])layout.getFirst();
     int [] rowHeights = (int [])layout.getSecond();
     return calculatePreferredLayoutSize(parent, columnWidths, rowHeights);
   }
 }
 /**
  * Calculates the preferred layout size for the specified preferred column
  * widths and row heights.
  */
 private Dimension calculatePreferredLayoutSize(Container parent, int [] columnWidths, int [] rowHeights){
   int prefWidth = 0;
   int prefHeight = 0;
   for (int i = 0; i < columnWidths.length; i++)
     prefWidth += columnWidths[i];
   for (int i = 0; i < rowHeights.length; i++)
     prefHeight += rowHeights[i];
   // Add the gaps
   prefWidth += xGap*(columnWidths.length - 1);
   prefHeight += yGap*(rowHeights.length - 1);
   // Add parent insets
   Insets parentInsets = parent.getInsets();
   prefWidth += parentInsets.left + parentInsets.right;
   prefHeight += parentInsets.top + parentInsets.bottom;
   
   return new Dimension(prefWidth, prefHeight);
 }
 /**
  * Returns the same as preferredLayoutSize.
  */
 public Dimension minimumLayoutSize(Container parent){
   return preferredLayoutSize(parent);
 }


 /**
  * Returns a dimension with maximum possible values.
  */
 public Dimension maximumLayoutSize(Container parent){
   return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
 }
 /**
  * Returns CENTER_ALIGNMENT;
  */
 public float getLayoutAlignmentX(Container parent) {
   return Component.CENTER_ALIGNMENT;
 }
 /**
  * Returns CENTER_ALIGNMENT;
  */
 public float getLayoutAlignmentY(Container parent) {
   return Component.CENTER_ALIGNMENT;
 }

} /**

* The utillib library.
* More information is available at http://www.jinchess.ru/.
* Copyright (C) 2002 Alexander Maryanovsky.
* All rights reserved.
*
* The utillib library is free software; you can redistribute
* it and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* The utillib library is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with utillib library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/**

* A wrapper for any two other given objects.
*/
final class Pair{
 
 /**
  * The first object.
  */
 private final Object first;


 /**
  * The second object.
  */
 private final Object second;


 /**
  * Creates a new Pair with the two given objects. Either of the
  * objects may be null.
  */
 public Pair(Object first, Object second){
   this.first = first;
   this.second = second;
 }


 /**
  * Returns the first object.
  */
 public Object getFirst(){
   return first;
 }


 /**
  * Returns the second object.
  */
 public Object getSecond(){
   return second;
 }


 /**
  * Returns a hashcode combined from the hashcodes of the two target objects.
  */
 public int hashCode(){
   int hash1 = (first == null ? 0 : first.hashCode());
   int hash2 = (second == null ? 0 : second.hashCode());
   return hash1^hash2;
 }


 /**
  * Returns true iff the given Object is a Pair, and its two objects are the
  * same as this one"s (comparison done via Utilities.areEqual)
  */
 public boolean equals(Object o){
   if (o == this)
     return true;
   if (!(o instanceof Pair))
     return false;
   Pair pair = (Pair)o;
   return Utilities.areEqual(pair.first, first) && Utilities.areEqual(pair.second, second);
 }

}

/**
 * The utillib library.
 * More information is available at http://www.jinchess.ru/.
 * Copyright (C) 2002, 2003 Alexander Maryanovsky.
 * All rights reserved.
 *
 * The utillib library is free software; you can redistribute
 * it and/or modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * The utillib library is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
 * General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with utillib library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA
 */
/**
 * A collection of general utility methods.
 */
 class Utilities{
  
  
  
  /**
   * A 0-length Object array.
   */
   
  public static final Object [] EMPTY_ARRAY = new Object[0];
  /**
   * A 0-length long array.
   */
   
  public static final long [] EMPTY_LONG_ARRAY = new long[0];
  /**
   * A 0-length int array.
   */
   
  public static final int [] EMPTY_INT_ARRAY = new int[0];
  
  
  /**
   * A 0-length short array.
   */
   
  public static final short [] EMPTY_SHORT_ARRAY = new short[0];
  
  /**
   * A 0-length byte array.
   */
   
  public static final byte [] EMPTY_BYTE_ARRAY = new byte[0];
  
  
  
  /**
   * A 0-length char array.
   */
   
  public static final char [] EMPTY_CHAR_ARRAY = new char[0];
  /**
   * A 0-length double array.
   */
   
  public static final double [] EMPTY_DOUBLE_ARRAY = new double[0];
  
  /**
   * A 0-length float array.
   */
   
  public static final float [] EMPTY_FLOAT_ARRAY = new float[0];
  /**
   * A 0-length String array.
   */
   
  public static final String [] EMPTY_STRING_ARRAY = new String[0];
  
  
  
  /**
   * An empty enumeration.
   */
  
  public static final Enumeration EMPTY_ENUM = new Enumeration(){
    public boolean hasMoreElements(){return false;}
    public Object nextElement(){throw new NoSuchElementException();}
  };
  
  
  /**
   * Returns true if the two specified objects are the same.
   * Returns false otherwise. To be considered the same, the two
   * references must either both be null or invoking equals on one
   * of them with the other must return true.
   */
  public static boolean areEqual(Object obj1, Object obj2){
    return (obj1 == obj2) || (obj1 == null ? false : obj1.equals(obj2));
  }


  /**
   * Maps the specified key to the specified value in the specified
   * Hashtable. If the specified value is null any
   * existing mapping of the specified key is removed from the
   * Hashtable. The old value mapped to the specified key
   * is returned, or null if no value was mapped to the key.
   */
  public static Object put(Hashtable table, Object key, Object value){
    return value == null ? table.remove(key) : table.put(key, value);
  }
  /**
   * Returns true if the specified object is an element of the
   * specified array. The specified array may not be null. The
   * specified object may be null, in which case this method will
   * return true iff one of the indices in the array is empty 
   * (contains null).
   */
  public static boolean contains(Object [] array, Object item){
    return (indexOf(array, item) != -1);
  }
  /**
   * Returns the index of the first occurrance of specified object in the
   * specified array, or -1 if the specified object is not an element of the
   * specified array. The specified object may be null in which
   * case the returned index will be the index of the first null
   * in the array.
   */
  public static int indexOf(Object [] array, Object item){
    if (array == null)
      throw new IllegalArgumentException("The specified array may not be null");
    for (int i = 0; i < array.length; i++)
      if (areEqual(item, array[i]))
        return i;
    return -1;
  }


  /**
   * Returns the index of the first occurrance of specified integer in the
   * specified array, or -1 if the specified integer is not an element of the
   * specified array.
   */
  public static int indexOf(int [] arr, int val){
    if (arr == null)
      throw new IllegalArgumentException("The specified array may not be null");
    for (int i = 0; i < arr.length; i++)
      if (arr[i] == val)
        return i;
    return -1;
  }
  
  
  /**
   * Converts the specified array into a string by appending all its elements
   * separated by a semicolon.
   */
  public static String arrayToString(Object [] arr){
    StringBuffer buf = new StringBuffer();
    for (int i = 0; i < arr.length; i++){
      buf.append(arr[i]);
      buf.append("; ");
    }
    if (arr.length > 0)
      buf.setLength(buf.length() - 2); // get rid of the extra "; "
    return buf.toString();
  }


  /**
   * Converts the specified Hashtable into a string by putting
   * each key and value on a separate line (separated by "\n") and an arrow
   * (" -> ") between them.
   */
  public static String hashtableToString(Hashtable hashtable){
    StringBuffer buf = new StringBuffer();
    Enumeration keys = hashtable.keys();
    while (keys.hasMoreElements()){
      Object key = keys.nextElement();
      Object value = hashtable.get(key);
      buf.append(key.toString());
      buf.append(" -> ");
      buf.append(value.toString());
      buf.append("\n");
    }
    return buf.toString();
  }


  /**
   * Returns the maximum element in the specified integer array.
   */
  public static int max(int [] arr){
    if (arr == null)
      throw new IllegalArgumentException("The specified array may not be null");
    if (arr.length == 0)
      throw new IllegalArgumentException("The specified array must have at least one element");
    int n = arr[0];
    for (int i = 1; i < arr.length; i++)
      if (arr[i] > n)
        n = arr[i];
    return n;
  }
  /**
   * Returns a hash code for the specified double value.
   */
  public static int hashCode(double val){
    return hashCode(Double.doubleToLongBits(val));
  }
  /**
   * Returns a hash code for the specified long value.
   */
  public static int hashCode(long val){
    return (int)(val ^ (val >>> 32));
  }
  
  
  
  /**
   * Returns the name of the package of the specified class.
   */
  
  public static String getPackageName(Class c){
    return getPackageName(c.getName());
  }
  
  
  
  /**
   * Returns the name of the package of the class with the specified (full) name.
   */
  
  public static String getPackageName(String className){
    int lastDotIndex = className.lastIndexOf(".");
    return lastDotIndex == -1 ? "" : className.substring(0, lastDotIndex);
  }
  
  
  
  /**
   * Returns the short name (excluding the package name) of the specified class. 
   */
  
  public static String getClassName(Class c){
    return getClassName(c.getName());
  }
  
  
  
  /**
   * Returns the short name (excluding the package name) of the class with the
   * specified fully qualified name.
   */
  
  public static String getClassName(String className){
    int lastDotIndex = className.lastIndexOf(".");
    return lastDotIndex == -1 ? className : className.substring(lastDotIndex + 1);
  }
  
  
  
}
  
   
   
   
 </source>
   
  
 
  



Table Layout implements LayoutManager2

   <source lang="java">
   

/* Copyright (c) 2006, 2009, Carl Burch. License information is located in the

* com.cburch.logisim.Main source code and at www.cburch.ru/logisim/. */

import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.LayoutManager2; import java.util.ArrayList; public class TableLayout implements LayoutManager2 {

   private int colCount;
   private ArrayList contents; // of Component[]
   private int curRow;
   private int curCol;
   private Dimension prefs;
   private int[] prefRow;
   private int[] prefCol;
   private double[] rowWeight;
   
   public TableLayout(int colCount) {
       this.colCount = colCount;
       this.contents = new ArrayList();
       this.curRow = 0;
       this.curCol = 0;
   }
   
   public void setRowWeight(int rowIndex, double weight) {
       if(weight < 0) {
           throw new IllegalArgumentException("weight must be nonnegative");
       }
       if(rowIndex < 0) {
           throw new IllegalArgumentException("row index must be nonnegative");
       }
       if((rowWeight == null || rowIndex >= rowWeight.length) && weight != 0.0) {
           double[] a = new double[rowIndex + 10];
           if(rowWeight != null) System.arraycopy(rowWeight, 0, a, 0, rowWeight.length);
           rowWeight = a;
       }
       rowWeight[rowIndex] = weight;
   }
   public void addLayoutComponent(String name, Component comp) {
       while(curRow >= contents.size()) {
           contents.add(new Component[colCount]);
       }
       Component[] rowContents = (Component[]) contents.get(curRow);
       rowContents[curCol] = comp;
       ++curCol;
       if(curCol == colCount) {
           ++curRow;
           curCol = 0;
       }
       prefs = null;
   }
   public void addLayoutComponent(Component comp, Object constraints) {
       if(constraints instanceof TableConstraints) {
           TableConstraints con = (TableConstraints) constraints;
           if(con.getRow() >= 0) curRow = con.getRow();
           if(con.getCol() >= 0) curCol = con.getCol();
       }
       addLayoutComponent("", comp);
   }
   public void removeLayoutComponent(Component comp) {
       for(int i = 0, n = contents.size(); i < n; i++) {
           Component[] row = (Component[]) contents.get(i);
           for(int j = 0; j < row.length; j++) {
               if(row[j] == comp) {
                   row[j] = null;
                   return;
               }
           }
       }
       prefs = null;
   }
   public Dimension preferredLayoutSize(Container parent) {
       if(prefs == null) {
           int[] prefCol = new int[colCount];
           int[] prefRow = new int[contents.size()]; 
           int height = 0;
           for(int i = 0; i < prefRow.length; i++) {
               Component[] row = (Component[]) contents.get(i);
               int rowHeight = 0;
               for(int j = 0; j < row.length; j++) {
                   if(row[j] != null) {
                       Dimension dim = row[j].getPreferredSize();
                       if(dim.height > rowHeight) rowHeight = dim.height;
                       if(dim.width > prefCol[j]) prefCol[j] = dim.width;
                   }
               }
               prefRow[i] = rowHeight;
               height += rowHeight;
           }
           int width = 0;
           for(int i = 0; i < prefCol.length; i++) {
               width += prefCol[i];
           }
           this.prefs = new Dimension(width, height);
           this.prefRow = prefRow;
           this.prefCol = prefCol;
       }
       return new Dimension(prefs);
   }
   public Dimension minimumLayoutSize(Container parent) {
       return preferredLayoutSize(parent);
   }
   public Dimension maximumLayoutSize(Container parent) {
       return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
   }
   public float getLayoutAlignmentX(Container parent) {
       return 0.5f;
   }
   public float getLayoutAlignmentY(Container parent) {
       return 0.5f;
   }
   public void layoutContainer(Container parent) {
       Dimension pref = preferredLayoutSize(parent);
       int[] prefRow = this.prefRow;
       int[] prefCol = this.prefCol;
       Dimension size = parent.getSize();
       
       double y0;
       int yRemaining = size.height - pref.height;
       double rowWeightTotal = 0.0;
       if(yRemaining != 0 && rowWeight != null) {
           for(int i = 0; i < rowWeight.length; i++) {
               rowWeightTotal += rowWeight[i];
           }
       }
       if(rowWeightTotal == 0.0 && yRemaining > 0) {
           y0 = yRemaining / 2.0;
       } else {
           y0 = 0;
       }
       
       int x0 = (size.width - pref.width) / 2;
       if(x0 < 0) x0 = 0;
       double y = y0;
       for(int i = 0, n = contents.size(); i < n; i++) {
           Component[] row = (Component[]) contents.get(i);
           int yRound = (int) (y + 0.5);
           int x = x0;
           for(int j = 0; j < row.length; j++) {
               Component comp = row[j];
               if(comp != null) {
                   row[j].setBounds(x, yRound, prefCol[j], prefRow[i]);
               }
               x += prefCol[j];
           }
           y += prefRow[i];
           if(rowWeightTotal > 0 && i < rowWeight.length) {
               y += yRemaining * rowWeight[i] / rowWeightTotal;
           }
       }
       
       
       // TODO Auto-generated method stub
       
   }
   public void invalidateLayout(Container parent) {
       prefs = null;
   }

} /* Copyright (c) 2006, 2009, Carl Burch. License information is located in the

* com.cburch.logisim.Main source code and at www.cburch.ru/logisim/. */
class TableConstraints {
   public static TableConstraints at(int row, int col) {
       return new TableConstraints(row, col);
   }
   
   private int col;
   private int row;
   
   private TableConstraints(int row, int col) {
       this.col = col;
       this.row = row;
   }
   
   int getRow() {
       return row;
   }
   
   int getCol() {
       return col;
   }

}



 </source>
   
  
 
  



Table layout manager

   <source lang="java">
   

// Table layout manager, with the flexibility of GridBagLayout but the ease // of use of HTML table declarations. // See http://www.parallax.co.uk/~rolf/download/table.html // Copyright (C) Rolf Howarth 1997, 1998 (rolf@parallax.co.uk) // Permission to freely use, modify and distribute this code is given, // provided this notice remains attached. This code is provided for // educational use only and no warranty as to its suitability for any // other purpose is made. // Modification history // 0.1 01 Nov 96 First version // 1.0 17 Jan 97 Minor bug fix; added column weighting. // 1.1 08 Apr 98 Don"t use methods deprecated in JDK1.1 // 1.2 16 Apr 98 Make own copy of Dimension objects as they"re not immutable import java.awt.*; import java.util.*; // Private class to parse and store the options for a single table entry

/**

* Table layout manager, with the flexibity of GridBagLayout but the ease of
* use of HTML table declarations.
*
*

use like: </br> * new TableLayout(cols) </br> * add(comp, new TableOption(..)) </br> * .. *

*/

public class TableLayout implements LayoutManager,LayoutManager2 {

 private Hashtable options = new Hashtable();
 private TableOption defaultOption;
 private int nrows=0, ncols=0;
 private int ncomponents=0;
 private Component[][] components=null;
 private int MinWidth=0, MinHeight=0, PrefWidth=0, PrefHeight=0;
 private int[] minWidth=null, minHeight=null, prefWidth=null, prefHeight=null;
 private int[] weight=null, columnWidth=null;
 private int hgap=0, vgap=0;
 /**
 * Construct a new table layout manager.
 * @param cols Number of columns, used when adding components to tell when to go to the next row
 * @param defaultAlignment Default defaultAlignment for cells if not specified at the time of adding the component
 * @param hgap Horizontal gap between cells and at edge (in pixels)
 * @param vgap Vertical gap between cells and at edge (in pixels)
 **/
 public TableLayout(int cols, String defaultAlignment, int hgap, int vgap) {
   this(cols, new TableOption(defaultAlignment),hgap,vgap);
 }
   public TableLayout(int cols, TableOption defaultAlignment, int hgap, int vgap) {
       this.ncols = cols;  // the number of columns is specified
   this.nrows = 0;   // the number of rows is calculated
       this.ruponents = new Component[cols][];
   this.defaultOption=defaultAlignment;
       this.hgap = hgap;
       this.vgap = vgap;
   }
 public TableLayout(int cols, String alignment)
 {
   this(cols, alignment, 0, 0);
 }
 public TableLayout(int cols)
 {
   this(cols, "", 0, 0);
 }
 public void addLayoutComponent(String alignment, Component comp)
 {
   options.put(comp, new TableOption(alignment));
 }
 public void removeLayoutComponent(Component comp)
 {
   options.remove(comp);
 }
 // Iterate through the components, counting the number of rows taking into account
 // row and column spanning, then initialise the components[c][r] matrix so that
 // we can retrieve the component at a particular row,column position.
 private void loadComponents(Container parent)
 {
   ncomponents = parent.getComponentCount();
   // If we haven"t allocated the right sized array for each column yet, do so now.
   // Note that the number of columns is fixed, but the number of rows is not know
   // and could in the worst case be up the number of components. Unfortunately this
   // means we need to allocate quite big arrays, but the alternative would require
   // complex multiple passes as we try to work out the effect of row spanning.
   if (components[0] == null || components[0].length < ncomponents)
   {
     for (int i=0; i<ncols; ++i)
       components[i] = new Component[ncomponents];
   }
   // Nullify the array
   for (int i=0; i<ncols; ++i)
   {
     for (int j=0; j<components[i].length; ++j)
       components[i][j] = null;
   }
   // fill the matrix with components, taking row/column spanning into account
   int row=0, col=0;
   for (int i=0; i<ncomponents; ++i)
   {
     // get the next component and its options
     Component comp = parent.getComponent(i);
     TableOption option = (TableOption) options.get(comp);
     if (option==null) option = defaultOption;
     // handle options to force us to column 0 or to skip columns
     if (option.forceColumn >= 0)
     {
       if (col > option.forceColumn)
         ++row;
       col = option.forceColumn;
     }
     col += option.skipColumns;
     if (col>=ncols) { ++row; col=0; }
     // skip over any cells that are already occupied
     while (components[col][row] != null)
     {
       ++col;
       if (col>=ncols) { ++row; col=0; }
     }
     // if using colspan, will we fit on this row?
     if (col+option.colSpan > ncols)
     {
       ++row;
       col = 0;
     }
     // for now, fill all the cells that are occupied by this component
     for (int c=0; c<option.colSpan; ++c)
       for (int r=0; r<option.rowSpan; ++r)
         components[col+c][row+r] = comp;
     // advance to the next cell, ready for the next component
     col += option.colSpan;
     if (col>=ncols) { ++row; col=0; }
   }
   // now we know how many rows there are
   if (col == 0)
     nrows = row;
   else
     nrows = row+1;
   // now we"ve positioned our components we can thin out the cells so
   // we only remember the top left corner of each component
   for (row=0; row<nrows; ++row)
   {
     for (col=0; col<ncols; ++col)
     {
       Component comp = components[col][row];
       for (int r=row; r<nrows && components[col][r]==comp; ++r)
       {
         for (int c=col; c<ncols && components[c][r]==comp; ++c)
         {
           if (r>row || c>col)
             components[c][r] = null;
         }
       }
     }
   }
 }
 private void measureComponents(Container parent)
 {
   // set basic metrics such as ncomponents & nrows, and load the components
   // into the components[][] array.
   loadComponents(parent);
   // allocate new arrays to store row and column preferred and min sizes, but
   // only if the old arrays aren"t big enough
   if (minWidth==null || minWidth.length<ncols)
   {
     minWidth = new int[ncols];
     prefWidth = new int[ncols];
     columnWidth = new int[ncols];
     weight = new int[ncols];
   }
   if (minHeight==null || minHeight.length<nrows)
   {
     minHeight = new int[nrows];
     prefHeight = new int[nrows];
   }
   int i;
   for (i=0; i<ncols; ++i)
   {
     minWidth[i] = 0;
     prefWidth[i] = 0;
   }
   for (i=0; i<nrows; ++i)
   {
     minHeight[i] = 0;
     prefHeight[i] = 0;
   }
   // measure the minimum and preferred size of each row and column
   for (int row=0; row<nrows; ++row)
   {
     for (int col=0; col<ncols; ++col)
     {
       Component comp = components[col][row];
       if (comp != null)
       {
         TableOption option = (TableOption) options.get(comp);
         if (option==null) option = defaultOption;
         Dimension minSize = new Dimension(comp.getMinimumSize());
         Dimension prefSize = new Dimension(comp.getPreferredSize());
         // enforce prefSize>=minSize
         if (prefSize.width < minSize.width)
           prefSize.width = minSize.width;
         if (prefSize.height < minSize.height)
           prefSize.height = minSize.height;
         // divide size across all the rows or columns being spanned
         minSize.width /= option.colSpan;
         minSize.height /= option.rowSpan;
         prefSize.width = (prefSize.width - hgap*(option.colSpan-1)) / option.colSpan;
         prefSize.height = (prefSize.height - vgap*(option.rowSpan-1)) / option.rowSpan;
         for (int c=0; c<option.colSpan; ++c)
         {
           if (minSize.width > minWidth[col+c])
             minWidth[col+c] = minSize.width;
           if (prefSize.width > prefWidth[col+c])
             prefWidth[col+c] = prefSize.width;
         }
         for (int r=0; r<option.rowSpan; ++r)
         {
           if (minSize.height > minHeight[row+r])
             minHeight[row+r] = minSize.height;
           if (prefSize.height > prefHeight[row+r])
             prefHeight[row+r] = prefSize.height;
         }
       }
     }
   }
   // add rows and columns to give total min and preferred size of whole grid
   MinWidth = 0;
   MinHeight = 0;
   PrefWidth = hgap;
   PrefHeight = vgap;
   for (i=0; i<ncols; ++i)
   {
     MinWidth += minWidth[i];
     PrefWidth += prefWidth[i] + hgap;
   }
   for (i=0; i<nrows; ++i)
   {
     MinHeight += minHeight[i];
     PrefHeight += prefHeight[i] + vgap;
   }
 }
 public Dimension minimumLayoutSize(Container parent)
 {
   Insets insets = parent.getInsets();
   measureComponents(parent);
   // System.out.println("Min Size: "+MinWidth+","+MinHeight);
   return new Dimension(insets.left + insets.right + MinWidth,
     insets.top + insets.bottom + MinHeight);
 }
 public Dimension preferredLayoutSize(Container parent)
 {
   Insets insets = parent.getInsets();
   measureComponents(parent);
   // System.out.println("Pref Size: "+PrefWidth+","+PrefHeight);
   // System.out.println("+ insets LR "+insets.left+"+"+insets.right+", TB "+insets.top+"+"+insets.bottom);
   return new Dimension(insets.left + insets.right + PrefWidth,
     insets.top + insets.bottom + PrefHeight);
 }
 public void layoutContainer(Container parent)
 {
   Insets insets = parent.getInsets();
   measureComponents(parent);
   int width = parent.getSize().width - (insets.left + insets.right);
   int height = parent.getSize().height - (insets.top + insets.bottom);
   // System.out.println("Resize "+width+","+height);
   // Decide whether to base our scaling on minimum or preferred sizes, or
   // a mixture of both, separately for width and height scaling.
   // This weighting also tells us how much of the hgap/vgap to use.
   double widthWeighting = 0.0;
   if (width >= PrefWidth || PrefWidth==MinWidth)
     widthWeighting = 1.0;
   else if (width <= MinWidth)
   {
     widthWeighting = 0.0;
     width = MinWidth;
   }
   else
     widthWeighting = (double)(width-MinWidth)/(double)(PrefWidth-MinWidth);
   double heightWeighting = 0.0;
   if (height >= PrefHeight || PrefHeight==MinHeight)
     heightWeighting = 1.0;
   else if (height <= MinHeight)
   {
     heightWeighting = 0.0;
     height = MinHeight;
   }
   else
     heightWeighting = (double)(height-MinHeight)/(double)(PrefHeight-MinHeight);
   // calculate scale factors to scale components to size of container, based
   // on weighted combination of minimum and preferred sizes
   double minWidthScale = (1.0 - widthWeighting) * width/MinWidth;
   //double prefWidthScale = widthWeighting * (width-hgap*(ncols+1))/(PrefWidth-hgap*(ncols+1));
   double minHeightScale = (1.0 - heightWeighting) * height/MinHeight;
   double prefHeightScale = heightWeighting * (height-vgap*(nrows+1))/(PrefHeight-vgap*(nrows+1));
   // only get the full amount of gap if we"re working to preferred size
   int vGap = (int) (vgap * heightWeighting);
   int hGap = (int) (hgap * widthWeighting);
   int y = insets.top + vGap;
   for (int c=0; c<ncols; ++c)
     weight[c] = prefWidth[c];
   for (int r=0; r<nrows; ++r)
   {
     int x = insets.left + hGap;
     int rowHeight = (int)(minHeight[r]*minHeightScale + prefHeight[r]*prefHeightScale);
     // Column padding can vary from row to row, so we need several
     // passes through the columns for each row:
     // First, work out the weighting that deterimines how we distribute column padding
     for (int c=0; c<ncols; ++c)
     {
       Component comp = components[c][r];
       if (comp != null)
       {
         TableOption option = (TableOption) options.get(comp);
         if (option==null) option = defaultOption;
         if (option.weight >= 0)
           weight[c] = option.weight;
         else if (option.weight == -1)
           weight[c] = prefWidth[c];
       }
     }
     int totalWeight = 0;
     for (int c=0; c<ncols; ++c)
       totalWeight += weight[c];
     int horizSurplus = width - hgap*(ncols+1) - PrefWidth;
     // Then work out column sizes, essentially preferred size + share of padding
     for (int c=0; c<ncols; ++c)
     {
       columnWidth[c] = (int) (minWidthScale * minWidth[c] + widthWeighting * prefWidth[c]);
       if (horizSurplus > 0 && totalWeight > 0)
         columnWidth[c] += (int) (widthWeighting * horizSurplus * weight[c] / totalWeight);
     }
     // Only now do we know enough to position all the columns within this row...
     for (int c=0; c<ncols; ++c)
     {
       Component comp = components[c][r];
       if (comp != null)
       {
         TableOption option = (TableOption) options.get(comp);
         if (option==null) option = defaultOption;
         // cell size may be bigger than row/column size due to spanning
         int cellHeight = rowHeight;
         int cellWidth = columnWidth[c];
         for (int i=1; i<option.colSpan; ++i)
           cellWidth += columnWidth[c+i];
         for (int i=1; i<option.rowSpan; ++i)
           cellHeight += (int)(minHeight[r+i]*minHeightScale + prefHeight[r+i]*prefHeightScale + vGap);
         Dimension d = new Dimension(comp.getPreferredSize());
         if (d.width > cellWidth || option.horizontal==TableOption.FILL)
           d.width = cellWidth;
         if (d.height > cellHeight || option.vertical==TableOption.FILL)
           d.height = cellHeight;
         int yoff = 0;
         if (option.vertical == TableOption.BOTTOM)
           yoff = cellHeight - d.height;
         else if (option.vertical == TableOption.CENTRE)
           yoff = (cellHeight - d.height) / 2;
         int xoff = 0;
         if (option.horizontal == TableOption.RIGHT)
           xoff = cellWidth - d.width;
         else if (option.horizontal == TableOption.CENTRE)
           xoff = (cellWidth - d.width) / 2;
         // System.out.println(" "+comp.getClass().getName()+" at ("+x+"+"+xoff+","+y+"+"+yoff+"), size "+d.width+","+d.height);
         comp.setBounds(x+xoff,y+yoff,d.width,d.height);
       }
       x += columnWidth[c] + hGap;
     }
     y += rowHeight + vGap;
   }
 }
   public void addLayoutComponent(Component comp, Object constraints) {
       if(constraints instanceof TableOption){
           options.put(comp, constraints);
       }
       else if(constraints==null){
           options.put(comp,defaultOption);
       }
       else throw new IllegalArgumentException("not a valid constraints object="+constraints);
   }
    /**
    * Returns the alignment along the x axis.  This specifies how
    * the component would like to be aligned relative to other
    * components.  The value should be a number between 0 and 1
    * where 0 represents alignment along the origin, 1 is aligned
    * the furthest away from the origin, 0.5 is centered, etc.
*

* @return the value 0.5f to indicate centered */ public float getLayoutAlignmentX(Container parent) { return 0.5f; } /** * Returns the alignment along the y axis. This specifies how * the component would like to be aligned relative to other * components. The value should be a number between 0 and 1 * where 0 represents alignment along the origin, 1 is aligned * the furthest away from the origin, 0.5 is centered, etc. * <p> * @return the value 0.5f to indicate centered */ public float getLayoutAlignmentY(Container parent) { return 0.5f; } /** * Invalidates the layout, indicating that if the layout manager * has cached information it should be discarded. */ public void invalidateLayout(Container target) { } /** * Returns the maximum dimensions for this layout given the components * in the specified target container. * @param target the container which needs to be laid out * @see Container * @see #minimumLayoutSize(Container) * @see #preferredLayoutSize(Container) * @return the maximum dimensions for this layout */ public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } } class TableOption{ public static final int CENTRE=1, FILL=2, LEFT=3, RIGHT=4, TOP=5, BOTTOM=6; int horizontal = CENTRE; int vertical = CENTRE; int rowSpan=1, colSpan=1, skipColumns=0, forceColumn=-1, weight=-2; /** * * @param horizontal one of CENTRE,FILL,LEFT,RIGHT,TOP,BOTTOM * @param vertical */ public TableOption(int horizontal, int vertical) { this.horizontal = horizontal; this.vertical = vertical; } public TableOption(int horizontal, int vertical, int rowSpan, int colSpan) { this.horizontal = horizontal; this.vertical = vertical; this.rowSpan = rowSpan; this.colSpan = colSpan; } public TableOption(int horizontal, int vertical, int rowSpan, int colSpan, int skipColumns, int forceColumn, int weight) { this.horizontal = horizontal; this.vertical = vertical; this.rowSpan = rowSpan; this.colSpan = colSpan; this.skipColumns = skipColumns; this.forceColumn = forceColumn; this.weight = weight; } TableOption(String alignment) { StringTokenizer tk = new StringTokenizer(alignment, ","); while (tk.hasMoreTokens()) { String token = tk.nextToken(); boolean ok = false; int delim = token.indexOf("="); if (token.equals("NW") || token.equals("W") || token.equals("SW")) { horizontal = LEFT; ok=true; } if (token.equals("NE") || token.equals("E") || token.equals("SE")) { horizontal = RIGHT; ok=true; } if (token.equals("N") || token.equals("C") || token.equals("F")) { horizontal = CENTRE; ok=true; } if (token.equals("F") || token.equals("FH")) { horizontal = FILL; ok=true; } if (token.equals("N") || token.equals("NW") || token.equals("NE")) { vertical = TOP; ok=true; } if (token.equals("S") || token.equals("SW") || token.equals("SE")) { vertical = BOTTOM; ok=true; } if (token.equals("W") || token.equals("C") || token.equals("E")) { vertical = CENTRE; ok=true; } if (token.equals("F") || token.equals("FV")) { vertical = FILL; ok=true; } if (delim>0) { int val = Integer.parseInt(token.substring(delim+1)); token = token.substring(0,delim); if (token.equals("CS") && val>0) { colSpan = val; ok=true; } else if (token.equals("RS") && val>0) { rowSpan = val; ok=true; } else if (token.equals("SKIP") && val>0) { skipColumns = val; ok=true; } else if (token.equals("COL")) { forceColumn = val; ok=true; } else if (token.equals("WT")) { weight = val; ok=true; } } if (!ok) throw new IllegalArgumentException("TableOption "+token); } } } </source>

Tile Layout

   <source lang="java">
   

import java.awt.*; import java.util.LinkedList; import java.io.Serializable; /*

* Relative Component Layout Manager
* Copyright (c) 1999 John Catherino
* The cajo project: https://cajo.dev.java.net
*
* For issues or suggestions mailto:cajo@dev.java.net
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License, at version
* 2.1 of the licence, or any later version published by the Free Software
* Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You can receive a copy of the GNU Lesser General Public License from their
* website, http://fsf.org/licenses/lgpl.html; or via snail mail, Free
* Software Foundation Inc., 51 Franklin Street, Boston MA 02111-1301, USA
*/

/**

* A rather unique LayoutManager. In addition to laying out components relative
* to the container, it also supports layout relative to components within
* the container. Its purpose is to support arbitrarily complex component
* layouts, of an unlimited number of components, within a single container. It
* can easily create complex layouts that would otherwise require many
* subpanels, and multiple standard layout managers. It also can create layouts
* that are completely impossible, with standard layout managers. These
* features make this layout manager extremely flexible, and makes
* advancedlayouts extremely fast. It just may be, the last and only
* LayoutManager you"ll ever need.
* <p>
* 
* Components can be laid out above, below, left, or right of either a
* referenced component in the panel, or to the panel itself. Its width and
* height can be specified with similar flexibility. Absolute and proportional
* bounds are also supported. In typical use, one or more "reference"
* tiles are laid, and the rest of the components are set relative to them.
* <p>
* 
* Usage example:
 * panel.add(new JLabel("Label text:"), new Object[]{
 *       new Integer(TileLayout.LEFTINDENT + TileLayout.NOOFFSET +
 *       TileLayout.PROPWIDTH + TileLayout.FULLHEIGHT), refComponent,
 *       new Insets(-5, 10, 5, 10), new Rectangle(0, 0, 333, 0)
 * // proportion rectangle 33.3%w
 *       });
 * </tt>

* * </blockquote> * <p> * * Up to four alignment constraints can be specified, their order does not * matter: * * <p>

*
    *
  • Positioning constants for indent, offset, width, and height *
  • A Component for placement relative to, otherwise the container *
  • A Rectangle for fixed and proportional component bounds *
  • Insets to trim the resulting component boundaries *

* <p> * * Note</u>: since the JRE draws components from last added * to first; the manager lays them out similarly. Therefore, in order to layout * relative to another component, the reference component must be added <u>after * the dependent one. I know this can be a drag at first, but it becomes * critically important when components are laid out on top of others, or * overlapping. This is a super cool capability of this layout manager. * * @version 1.0, 01-Nov-99 Initial release * @author John Catherino */ public final class TileLayout implements LayoutManager2, Serializable { private static final long serialVersionUID = 1L; private static final Dimension NONE = new Dimension(); private final LinkedList components = new LinkedList(); private final LinkedList constraints = new LinkedList(); private void align(Dimension cont, Object cons[], Component comp) { int align = 0; Insets insets = null; Rectangle tile = null, fixd = null; if (cons != null) { for (int i = 0; i < cons.length; i++) { // gather constraints if (cons[i] != null) { if (cons[i] instanceof Rectangle) fixd = (Rectangle)cons[i]; else if (cons[i] instanceof Insets) insets = (Insets)cons[i]; else if (cons[i] instanceof Integer) align = ((Integer)cons[i]).intValue(); else if (cons[i] instanceof Component) tile = ((Component)cons[i]).getBounds(); } } } if (tile == null) tile = new Rectangle(cont); Rectangle pref = new Rectangle(tile.getLocation(), comp.getPreferredSize()); // perform component positioning: if ((align & 0x004000) != 0) pref.width = fixd.width; else if ((align & 0x008000) != 0) pref.width = (tile.width * fixd.width + 500) / 1000; else if ((align & 0x010000) != 0) pref.width = tile.width; if ((align & 0x080000) != 0) pref.height = fixd.height; else if ((align & 0x100000) != 0) pref.height = (tile.height * fixd.height + 500) / 1000; else if ((align & 0x200000) != 0) pref.height = tile.height; if ((align & 0x000001) != 0) pref.x -= pref.width; else if ((align & 0x000002) != 0) pref.x += (tile.width - pref.width >> 1); else if ((align & 0x000004) != 0) pref.x += tile.width - pref.width; else if ((align & 0x000008) != 0) pref.x += tile.width; else if ((align & 0x000010) != 0) pref.x += fixd.x; else if ((align & 0x000020) != 0) pref.x += (tile.width * fixd.x + 500) / 1000; if ((align & 0x000040) != 0) pref.y -= pref.height; else if ((align & 0x000080) != 0) pref.y += (tile.height - pref.height >> 1); else if ((align & 0x000100) != 0) pref.y += tile.height - pref.height; else if ((align & 0x000200) != 0) pref.y += tile.height; else if ((align & 0x000400) != 0) pref.y += fixd.y; else if ((align & 0x000800) != 0) pref.y += (tile.height * fixd.y + 500) / 1000; if ((align & 0x001000) != 0) pref.setBounds(0, pref.y, pref.x + pref.width, pref.height); else if ((align & 0x002000) != 0) pref.width = cont.width - pref.x; if ((align & 0x020000) != 0) pref.setBounds(pref.x, 0, pref.width, pref.y + pref.height); else if ((align & 0x040000) != 0) pref.height = cont.height - pref.y; if (insets != null) { // apply insets, if any: pref.x += insets.left; pref.y += insets.top; pref.width -= insets.left + insets.right; pref.height -= insets.top + insets.bottom; } // Note: this can cause surprising results, so use it, if you dare. :-) // Honour component minimum size: Dimension d = comp.getMinimumSize(); if (pref.width < d.width) pref.width = d.width; if (pref.height < d.height) pref.height = d.height; comp.setBounds(pref); // now the tile is set! } /** * This constant specifies placement of the component even with the left * border of the provided reference component, otherwise to the container * itself. */ public static final int NOINDENT = 0x000000; /** * This constant specifies placement of the component with its right border * one pixel to the left of the provided reference component, otherwise to * the container itself. */ public static final int LEFTINDENT = 0x000001; /** * This constant specifies placement of the component evenly between the left * and right borders of the provided reference component, otherwise to the * container itself. */ public static final int CENTERINDENT = 0x000002; /** * This constant specifies placement of the component with its right border * evenly aligned with the right border of the provided reference component, * otherwise to the container itself. */ public static final int FULLINDENT = 0x000004; /** * This constant specifies placement of the left border of the component one * pixel to the right of the provided reference component origin, otherwise * to the container itself. */ public static final int RIGHTINDENT = 0x000008; /** * Used in conjunction with a Rectangle constraint, the x value represents * the desired component indent as a fixed number of pixels right of the * provided component origin, otherwise to the container itself. */ public static final int FIXEDINDENT = 0x000010; /** * Used in conjunction with a Rectangle constraint, the x value represents * the desired component indent as a percentage (2000 = 200.0%) of a provided * component, otherwise to the container itself. */ public static final int PROPINDENT = 0x000020; /** * This constant specifies placement of the component even with the top * border of the provided reference component, otherwise to the container * itself. */ public static final int NOOFFSET = 0x000000; /** * This constant specifies placement of the component with its bottom border * one pixel above the provided reference component, otherwise to the * container itself. */ public static final int TOPOFFSET = 0x000040; /** * This constant specifies placement of the component evenly between the top * and bottom borders of the provided reference component, otherwise to the * container itself. */ public static final int CENTEROFFSET = 0x000080; /** * This constant specifies placement of the component with its bottom border * evenly aligned with the bottom border of the provided reference component, * otherwise to the container itself. */ public static final int FULLOFFSET = 0x000100; /** * This constant specifies placement of the top border of the component one * pixel below the provided reference component origin, otherwise to the * container itself. */ public static final int BOTTOMOFFSET = 0x000200; /** * Used in conjunction with a Rectangle constraint, the y value represents * the desired component offset as a fixed number of pixels below the * provided component origin, otherwise to the container itself. */ public static final int FIXEDOFFSET = 0x000400; /** * Used in conjunction with a Rectangle constraint, the y value represents * the desired component offset as a percentage (2000 = 200.0%) of a provided * component, otherwise to the container itself. */ public static final int PROPOFFSET = 0x000800; /** * This constant specifies that the component have its preferred width, as * returned by its getPreferredSize method. */ public static final int PREFWIDTH = 0x000000; /** * This constant specifies that the component be made wide enough such that * given its computed right margin, its left margin will align with that of * its container. */ public static final int CLAMPLEFT = 0x001000; /** * This constant specifies that the component be made wide enough such that * given its computed origin, its right margin will align with that of its * container. */ public static final int CLAMPRIGHT = 0x002000; /** * Used in conjunction with a Rectangle constraint, the width value * represents the desired component width as a fixed number of pixels. */ public static final int FIXEDWIDTH = 0x004000; /** * Used in conjunction with a Rectangle constraint, the width value * represents the desired component offset as a percentage (2000 = 200.0%) of * a provided component, otherwise to the container itself. */ public static final int PROPWIDTH = 0x008000; /** * This constant specifies that the component be made exactly as wide as its * reference component, otherwise as the container itself. */ public static final int FULLWIDTH = 0x010000; /** * This constant specifies that the component have its preferred height, as * returned by its getPreferredSize method. */ public static final int PREFHEIGHT = 0x000000; /** * This constant specifies that the component be made high enough such that * given its computed bottom margin, its top margin will align with that of * its container. */ public static final int CLAMPTOP = 0x020000; /** * This constant specifies that the component be made high enough such that * given its computed origin, its bottom margin will align with that of its * container. */ public static final int CLAMPBOTTOM = 0x040000; /** * Used in conjunction with a Rectangle constraint, the height value * represents the desired component width as a fixed number of pixels. */ public static final int FIXEDHEIGHT = 0x080000; /** * Used in conjunction with a Rectangle constraint, the height value * represents the desired component offset as a percentage (2000 = 200.0%) of * a provided component, otherwise to the container itself. */ public static final int PROPHEIGHT = 0x100000; /** * This constant specifies that the component be made exactly as high as its * reference component, otherwise as the container itself. */ public static final int FULLHEIGHT = 0x200000; /** * A frequently used position, used in conjunction with a reference * component, it will locate the component directly over, with the same width * and height. */ public static final Integer ABOVE = new Integer(NOINDENT + TOPOFFSET + FULLWIDTH + FULLHEIGHT); /** * A frequently used position, used in conjunction with a reference * component, it will locate the component directly beneath, with the same * width and height. */ public static final Integer BELOW = new Integer(NOINDENT + BOTTOMOFFSET + FULLWIDTH + FULLHEIGHT); /** * A frequently used position, used in conjunction with a reference * component, it will locate the component directly adjacent, to its right, * with the same width and height. */ public static final Integer RIGHT = new Integer(RIGHTINDENT + NOOFFSET + FULLWIDTH + FULLHEIGHT); /** * A frequently used position, used in conjunction with a reference * component, it will locate the component directly adjacent, to its left, * with the same width and height. */ public static final Integer LEFT = new Integer(LEFTINDENT + NOOFFSET + FULLWIDTH + FULLHEIGHT); /** * A frequently used position, it will render the component using the exact * size of the reference component, or container. */ public static final Integer FULLSIZE = new Integer(NOINDENT + NOOFFSET + FULLWIDTH + FULLHEIGHT); /** * Nothing is performed in the constructor, it is bodyless. */ public TileLayout() {} /** * The primary component addition method. Components are added for layout, * and its constraints are provided as an Object array. Up to 4 constraints * may be specified, and their order is not important. The following are the * applicable constraints:

*
    * <p> *
  • Rectangle for fixed or proportional component bounds *
  • Insets to trim the final boundaries after computation *
  • Integer of TileLayout positioning constants *
  • Component for relative placement, instead of container *

* * @param comp The component to be laid out within the container. * @param cons An Object[] containing 1 or more constraints. */ public void addLayoutComponent(Component comp, Object cons) { components.add(comp); constraints.add(cons); } /** * This method will make the added component exactly the same size as the * container itself. It is useful for adding wallpaper. * * @param comp The component to fill the container. * @param name The name of the component, unused by TileLayout. */ public void addLayoutComponent(String name, Component comp) { components.add(comp); constraints.add(new Object[]{ FULLSIZE }); } /** * As expected, removes the component from the ordered layout list. */ public void removeLayoutComponent(Component comp) { for (int i = 0; i < components.size(); i++) { if (components.get(i) == comp) { components.remove(i); constraints.remove(i); return; } } throw new IllegalArgumentException("Component not in container"); } /** * Lays out the components, last added to first added, according to their * specified constraints. */ public void layoutContainer(Container parent) { Dimension container = parent.getSize(); for (int i = components.size() - 1; i >= 0; i--) align(container, (Object[])constraints.get(i), (Component)components.get(i)); } /** * Bodyless implementation, as TileLayout uses no cached information. */ public void invalidateLayout(Container target) {} /** * Indicate center alignment. */ public float getLayoutAlignmentX(Container target) { return 0.5F; } /** * Indicate center alignment. */ public float getLayoutAlignmentY(Container target) { return 0.5F; } /** * Indicates no minimum size. */ public Dimension minimumLayoutSize(Container parent) { return NONE; } /** * Indicates no maximum size. */ public Dimension maximumLayoutSize(Container parent) { return NONE; } /** * Indicates no preferred size. */ public Dimension preferredLayoutSize(Container parent) { return NONE; } }



</source>





Wrapper Layout

<source lang="java">

/* GNU LESSER GENERAL PUBLIC LICENSE Copyright (C) 2006 The Lobo Project This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Contact info: lobochief@users.sourceforge.net

  • /

/* * Created on Mar 19, 2005 */ import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.LayoutManager; /** * @author J. H. S. */ public class WrapperLayout implements LayoutManager { /* (non-Javadoc) * @see java.awt.LayoutManager#addLayoutComponent(java.lang.String, java.awt.ruponent) */ public void addLayoutComponent(String arg0, Component arg1) { } /* (non-Javadoc) * @see java.awt.LayoutManager#removeLayoutComponent(java.awt.ruponent) */ public void removeLayoutComponent(Component arg0) { } /* (non-Javadoc) * @see java.awt.LayoutManager#preferredLayoutSize(java.awt.Container) */ public Dimension preferredLayoutSize(Container arg0) { java.awt.Insets insets = arg0.getInsets(); int count = arg0.getComponentCount(); if(count > 0) { Dimension d = arg0.getComponent(0).getPreferredSize(); return new Dimension(d.width + insets.left + insets.right, d.height + insets.top + insets.bottom); } else { return new Dimension(insets.left + insets.right, insets.top + insets.bottom); } } /* (non-Javadoc) * @see java.awt.LayoutManager#minimumLayoutSize(java.awt.Container) */ public Dimension minimumLayoutSize(Container arg0) { java.awt.Insets insets = arg0.getInsets(); int count = arg0.getComponentCount(); if(count > 0) { Dimension d = arg0.getComponent(0).getMinimumSize(); return new Dimension(d.width + insets.left + insets.right, d.height + insets.top + insets.bottom); } else { return new Dimension(insets.left + insets.right, insets.top + insets.bottom); } } /* (non-Javadoc) * @see java.awt.LayoutManager#layoutContainer(java.awt.Container) */ public void layoutContainer(Container arg0) { int count = arg0.getComponentCount(); if(count > 0) { Component child = arg0.getComponent(0); java.awt.Insets insets = arg0.getInsets(); child.setBounds(insets.left, insets.top, arg0.getWidth() - insets.left - insets.right, arg0.getHeight() - insets.top - insets.bottom); } }

private static WrapperLayout instance = new WrapperLayout();

public static WrapperLayout getInstance() { return instance; } }



</source>





X Y Layout

<source lang="java">

//Revised from enhydra swing import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.Insets; import java.awt.LayoutManager2; import java.awt.Rectangle; import java.io.Serializable; import java.util.Hashtable; public class XYLayout implements LayoutManager2, Serializable { private static final long serialVersionUID = 200L; int width; int height; Hashtable info; static final XYConstraints defaultConstraints = new XYConstraints(); public XYLayout() { info = new Hashtable(); } public XYLayout(int width, int height) { info = new Hashtable(); this.width = width; this.height = height; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public String toString() { return String.valueOf(String.valueOf((new StringBuffer("XYLayout[width=")).append(width) .append(",height=").append(height).append("]"))); } public void addLayoutComponent(String s, Component component1) { } public void removeLayoutComponent(Component component) { info.remove(component); } public Dimension preferredLayoutSize(Container target) { return getLayoutSize(target, true); } public Dimension minimumLayoutSize(Container target) { return getLayoutSize(target, false); } public void layoutContainer(Container target) { Insets insets = target.getInsets(); int count = target.getComponentCount(); for (int i = 0; i < count; i++) { Component component = target.getComponent(i); if (component.isVisible()) { Rectangle r = getComponentBounds(component, true); component.setBounds(insets.left + r.x, insets.top + r.y, r.width, r.height); } } } public void addLayoutComponent(Component component, Object constraints) { if (constraints instanceof XYConstraints) info.put(component, constraints); } public Dimension maximumLayoutSize(Container target) { return new Dimension(0x7fffffff, 0x7fffffff); } public float getLayoutAlignmentX(Container target) { return 0.5F; } public float getLayoutAlignmentY(Container target) { return 0.5F; } public void invalidateLayout(Container container) { } Rectangle getComponentBounds(Component component, boolean doPreferred) { XYConstraints constraints = (XYConstraints) info.get(component); if (constraints == null) constraints = defaultConstraints; Rectangle r = new Rectangle(constraints.x, constraints.y, constraints.width, constraints.height); if (r.width <= 0 || r.height <= 0) { Dimension d = doPreferred ? component.getPreferredSize() : component.getMinimumSize(); if (r.width <= 0) r.width = d.width; if (r.height <= 0) r.height = d.height; } return r; } Dimension getLayoutSize(Container target, boolean doPreferred) { Dimension dim = new Dimension(0, 0); if (width <= 0 || height <= 0) { int count = target.getComponentCount(); for (int i = 0; i < count; i++) { Component component = target.getComponent(i); if (component.isVisible()) { Rectangle r = getComponentBounds(component, doPreferred); dim.width = Math.max(dim.width, r.x + r.width); dim.height = Math.max(dim.height, r.y + r.height); } } } if (width > 0) dim.width = width; if (height > 0) dim.height = height; Insets insets = target.getInsets(); dim.width += insets.left + insets.right; dim.height += insets.top + insets.bottom; return dim; } } class XYConstraints implements Cloneable, Serializable { int x; int y; int width; int height; public XYConstraints() { this(0, 0, 0, 0); } public XYConstraints(int x, int y, int width, int height) { this.x = x; this.y = y; this.width = width; this.height = height; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public int hashCode() { return x ^ y * 37 ^ width * 43 ^ height * 47; } public boolean equals(Object that) { if (that instanceof XYConstraints) { XYConstraints other = (XYConstraints) that; return other.x == x && other.y == y && other.width == width && other.height == height; } else { return false; } } public Object clone() { return new XYConstraints(x, y, width, height); } public String toString() { return String.valueOf(String.valueOf((new StringBuffer("XYConstraints[")).append(x).append(",") .append(y).append(",").append(width).append(",").append(height).append("]"))); } }



</source>