Java Tutorial/Swing/Custom Layout
Содержание
- 1 A layout manager that displays a single component in the center of its container.
- 2 A layout manager that lays out components along a central axis
- 3 A simple layoutmanager to overlay all components of a parent.
- 4 Center Layout
- 5 Circle Layout
- 6 Compents are laid out in a circle.
- 7 Custom Layout: DiagonalLayout
- 8 DividerLayout is layout that divides two components with the column of actions
- 9 GraphPaperLayout implements LayoutManager2
- 10 Specialised layout manager for a grid of components.
- 11 Stack Layout, uses an orientation to determine if the contents should be arranged horizontally or vertically.
- 12 This LayoutManager arranges the components into a column. Components are always given their preferred size
- 13 Wrapper Layout
- 14 X Y Layout
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("1"), new Rectangle(0, 0, 1, 1));
* // Add a 2x1 Rect at (2,0)
* add(new Button("2"), new Rectangle(2, 0, 2, 1));
* // Add a 1x2 Rect at (1,1)
* add(new Button("3"), new Rectangle(1, 1, 1, 2));
* // Add a 2x2 Rect at (3,2)
* add(new Button("4"), new Rectangle(3, 2, 2, 2));
* // Add a 1x1 Rect at (0,4)
* add(new Button("5"), new Rectangle(0, 4, 1, 1));
* // Add a 1x2 Rect at (2,3)
* add(new Button("6"), new Rectangle(2, 3, 1, 2));
* }
* }
* </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("]")));
}
}