Java Tutorial/Swing/Custom Layout — различия между версиями

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

Текущая версия на 15:31, 31 мая 2010

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

/*
 * 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
  }
}





A layout manager that lays out components along a central axis

import java.awt.ruponent;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class FormLayoutTester {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.setLayout(new FormLayout());
    frame.add(new JLabel("A"));
    frame.add(new JTextField(15));
    frame.add(new JLabel("AA"));
    frame.add(new JTextField(20));
    frame.add(new JLabel("AAAA"));
    frame.add(new JTextField(10));
    frame.add(new JLabel("AAAAAA"));
    frame.add(new JTextField(2));
    frame.add(new JLabel("AAAAAAAA"));
    frame.add(new JTextField(5));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setVisible(true);
  }
}
/**
 * A layout manager that lays out components along a central axis
 */
class FormLayout implements LayoutManager {
  private int left;
  private int right;
  private int height;
  private static final int GAP = 6;
  
  public Dimension preferredLayoutSize(Container parent) {
    Component[] components = parent.getComponents();
    left = 0;
    right = 0;
    height = 0;
    for (int i = 0; i < components.length; i += 2) {
      Component cleft = components[i];
      Component cright = components[i + 1];
      Dimension dleft = cleft.getPreferredSize();
      Dimension dright = cright.getPreferredSize();
      left = Math.max(left, dleft.width);
      right = Math.max(right, dright.width);
      height = height + Math.max(dleft.height, dright.height);
    }
    return new Dimension(left + GAP + right, height);
  }
  public Dimension minimumLayoutSize(Container parent) {
    return preferredLayoutSize(parent);
  }
  public void layoutContainer(Container parent) {
    preferredLayoutSize(parent); // Sets left, right
    Component[] components = parent.getComponents();
    Insets insets = parent.getInsets();
    int xcenter = insets.left + left;
    int y = insets.top;
    for (int i = 0; i < components.length; i += 2) {
      Component cleft = components[i];
      Component cright = components[i + 1];
      Dimension dleft = cleft.getPreferredSize();
      Dimension dright = cright.getPreferredSize();
      int height = Math.max(dleft.height, dright.height);
      cleft.setBounds(xcenter - dleft.width, y + (height - dleft.height) / 2,
          dleft.width, dleft.height);
      cright.setBounds(xcenter + GAP, y + (height - dright.height) / 2,
          dright.width, dright.height);
      y += height;
    }
  }
  public void addLayoutComponent(String name, Component comp) {
  }
  public void removeLayoutComponent(Component comp) {
  }
}





A simple layoutmanager to overlay all components of a parent.

/* 
 * 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 <code>comp</code> to the layout,
     * associating it
     * with the string specified by <code>name</code>.
     *
     * @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);
        }
    }
}





Center Layout

/*
    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;
    }
}





Circle Layout

/**
 * This layout manager allows you to place components to form a circle within a
 * Container
 * 
 * @author Oscar De Leon oedeleon@netscape.net
 * 
 */
import java.awt.ruponent;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class CircleLayoutDemo {
  public static void main(String a[]) {
    JFrame frame = new JFrame();
    JPanel circle = new JPanel();
    circle.setLayout(new CircleLayout(true));
    for (int i = 0; i < 10; i++) {
      circle.add(new JLabel("circle_" + i * 7));
    }
    frame.setContentPane(circle);
    frame.setSize(200, 400);
    frame.setVisible(true);
  }
}
/**
 * This layout manager allows you to place components to form a circle within a
 * Container
 * 
 * @author Oscar De Leon oedeleon@netscape.net
 * 
 */
class CircleLayout implements LayoutManager {
  ArrayList components;
  ArrayList names;
  private boolean isCircle;
  /**
   * Creates a new CircleLayout that lays out components in a perfect circle
   */
  public CircleLayout() {
    this(true);
  }
  /**
   * Creates a new CircleLayout that lays out components in either an Ellipse or
   * a Circle. Ellipse Layout is not yet implemented.
   * 
   * @param circle
   *          Indicated the shape to use. It"s true for circle or false for
   *          ellipse.
   */
  public CircleLayout(boolean circle) {
    isCircle = circle;
  }
  /**
   * For compatibility with LayoutManager interface
   */
  public void addLayoutComponent(String name, Component comp) {
  }
  /**
   * Arranges the parent"s Component objects in either an Ellipse or a Circle.
   * Ellipse is not yet implemented.
   */
  public void layoutContainer(Container parent) {
    int x, y, w, h, s, c;
    int n = parent.getComponentCount();
    double parentWidth = parent.getSize().width;
    double parentHeight = parent.getSize().height;
    Insets insets = parent.getInsets();
    int centerX = (int) (parentWidth - (insets.left + insets.right)) / 2;
    int centerY = (int) (parentHeight - (insets.top + insets.bottom)) / 2;
    Component comp = null;
    Dimension compPS = null;
    if (n == 1) {
      comp = parent.getComponent(0);
      x = centerX;
      y = centerY;
      compPS = comp.getPreferredSize();
      w = compPS.width;
      h = compPS.height;
      comp.setBounds(x, y, w, h);
    } else {
      double r = (Math.min(parentWidth - (insets.left + insets.right), parentHeight
          - (insets.top + insets.bottom))) / 2;
      r *= 0.75; // Multiply by .75 to account for extreme right and bottom
                  // Components
      for (int i = 0; i < n; i++) {
        comp = parent.getComponent(i);
        compPS = comp.getPreferredSize();
        if (isCircle) {
          c = (int) (r * Math.cos(2 * i * Math.PI / n));
          s = (int) (r * Math.sin(2 * i * Math.PI / n));
        } else {
          c = (int) ((centerX * 0.75) * Math.cos(2 * i * Math.PI / n));
          s = (int) ((centerY * 0.75) * Math.sin(2 * i * Math.PI / n));
        }
        x = c + centerX;
        y = s + centerY;
        w = compPS.width;
        h = compPS.height;
        comp.setBounds(x, y, w, h);
      }
    }
  }
  /**
   * Returns this CircleLayout"s preferred size based on its Container
   * 
   * @param target
   *          This CircleLayout"s target container
   * @return The preferred size
   */
  public Dimension preferredLayoutSize(Container target) {
    return target.getSize();
  }
  /**
   * Returns this CircleLayout"s minimum size based on its Container
   * 
   * @param target
   *          This CircleLayout"s target container
   * @return The minimum size
   */
  public Dimension minimumLayoutSize(Container target) {
    return target.getSize();
  }
  /**
   * For compatibility with LayoutManager interface
   */
  public void removeLayoutComponent(Component comp) {
  }
  /**
   * Returns a String representation of this CircleLayout.
   * 
   * @return A String that represents this CircleLayout
   */
  public String toString() {
    return this.getClass().getName();
  }
}





Compents are laid out in a circle.

/* 
 * 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);
    }
}





Custom Layout: DiagonalLayout

/*
 *
 * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Sun.
 *
 * 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 AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE 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 SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control of
 * aircraft, air traffic, aircraft navigation or aircraft communications; or in
 * the design, construction, operation or maintenance of any nuclear
 * facility. Licensee represents and warrants that it will not use or
 * redistribute the Software for such purposes.
 */

/*
 * CustomLayoutDemo.java 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() {
        //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 + "]";
    }
}





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

/*
 * $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>
 * <code>DividerLayout</code> 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.
 * </p>
 * <p>
 *   Components are indicated as {@link #WEST}, {@link #EAST} and {@link #CENTER}.
 * </p>
 * 
 * @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);
   }
 }

}





GraphPaperLayout implements LayoutManager2

/*
 *
 * Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Sun.
 *
 * 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 AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE 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 SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control of
 * aircraft, air traffic, aircraft navigation or aircraft communications; or in
 * the design, construction, operation or maintenance of any nuclear
 * facility. Licensee represents and warrants that it will not use or
 * redistribute the Software for such purposes.
 */
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.LayoutManager2;
import java.awt.Rectangle;
import java.util.Hashtable;
import javax.swing.JFrame;
/**
 * The <code>GraphPaperLayout</code> 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.
 * <P>
 * <code><pre>
 * 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(&quot;1&quot;), new Rectangle(0, 0, 1, 1));
 *     // Add a 2x1 Rect at (2,0)
 *     add(new Button(&quot;2&quot;), new Rectangle(2, 0, 2, 1));
 *     // Add a 1x2 Rect at (1,1)
 *     add(new Button(&quot;3&quot;), new Rectangle(1, 1, 1, 2));
 *     // Add a 2x2 Rect at (3,2)
 *     add(new Button(&quot;4&quot;), new Rectangle(3, 2, 2, 2));
 *     // Add a 1x1 Rect at (0,4)
 *     add(new Button(&quot;5&quot;), new Rectangle(0, 4, 1, 1));
 *     // Add a 1x2 Rect at (2,3)
 *     add(new Button(&quot;6&quot;), new Rectangle(2, 3, 1, 2));
 *   }
 * }
 * </pre></code>
 * 
 * @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<Component, Rectangle> 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<Component, Rectangle>();
  }
  /**
   * @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
   * <code>getLargestCellSize()</code> 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 <code>getLargestCellSize()</code> 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 = 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 = 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
  }
}
public class DemoGraphPaperLayout {
  public static void main(String[] a) {
    JFrame frame = new JFrame();
    frame.setLayout(new GraphPaperLayout(new Dimension(5, 5)));
    // Add a 1x1 Rect at (0,0)
    frame.add(new Button("1"), new Rectangle(0, 0, 1, 1));
    // Add a 2x1 Rect at (2,0)
    frame.add(new Button("2"), new Rectangle(2, 0, 2, 1));
    // Add a 1x2 Rect at (1,1)
    frame.add(new Button("3"), new Rectangle(1, 1, 1, 2));
    // Add a 2x2 Rect at (3,2)
    frame.add(new Button("4"), new Rectangle(3, 2, 2, 2));
    // Add a 1x1 Rect at (0,4)
    frame.add(new Button("5"), new Rectangle(0, 4, 1, 1));
    // Add a 1x2 Rect at (2,3)
    frame.add(new Button("6"), new Rectangle(2, 3, 1, 2));
    frame.pack();
    frame.setVisible(true);
  }
}





Specialised layout manager for a grid of components.

/* 
 * 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
    }
}





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

/*
 *  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;
  }

}





This LayoutManager arranges the components into a column. Components are always given their preferred size

/*
 * Copyright (c) 2004 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 3nd 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,
 * including teaching and use in open-source projects.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book, 
 * please visit http://www.davidflanagan.ru/javaexamples3.
 */
import java.awt.ruponent;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.LayoutManager2;
import javax.swing.JButton;
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;
  }
}
/*
 * Copyright (c) 2004 David Flanagan. All rights reserved. This code is from the
 * book Java Examples in a Nutshell, 3nd 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, including teaching and use in open-source
 * projects. You may distribute it non-commercially as long as you retain this
 * notice. For a commercial use license, or to purchase the book, please visit
 * http://www.davidflanagan.ru/javaexamples3.
 */
class ColumnLayoutPane extends JPanel {
  public ColumnLayoutPane() {
    // Specify a ColumnLayout LayoutManager, with right alignment
    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);
    }
  }
}





Wrapper Layout

/*
    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;
    }
}





X Y Layout

//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("]")));
  }
}