import java.awt.*; import javax.swing.*; import java.awt.LayoutManager; import java.awt.Insets; import java.util.ArrayList; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; // give positions and sizes for all widgets public class DemoAlignLayout extends JFrame { public static void main(String[] args) { DemoAlignLayout demo = new DemoAlignLayout(); } DemoAlignLayout() { this.setSize(800, 300); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // layout this.setLayout(new AlignLayout(40, 40)); // add components JComponent c; c = new JLabel("Number"); // try uncommenting this // c.setPreferredSize(new Dimension(200, 50)); debugBorder(c); this.add(c); c = new JSlider(0, 100, 50); debugBorder(c); this.add(c); c = new JLabel("Choice"); debugBorder(c); this.add(c); // create a radio button group ButtonGroup radiobuttons = new ButtonGroup(); JPanel radioPanel = new JPanel(new GridLayout(1, 0)); for (String s: new String[] {"A", "B", "C"}) { JRadioButton rb = new JRadioButton(s); radiobuttons.add(rb); radioPanel.add(rb); } debugBorder(radioPanel); this.add(radioPanel); System.out.println("Preferred size: " + this.getPreferredSize()); System.out.println("Minimum size: " + this.getMinimumSize()); this.setVisible(true); } // I made this to make it easy to add some debug information void debugBorder(JComponent c) { // try uncommenting this c.setBorder(BorderFactory.createLineBorder(Color.black)); } } /** * A layout manager that arranges components in a horizontal line equally spaced * and centred vertically in the parent container. */ class AlignLayout implements LayoutManager { int minimumSpacing; int preferredSpacing; /** Construct a new AlignLayout object with spacing between components. */ public AlignLayout(int minSpacing, int preferredSpacing) { super(); this.minimumSpacing = minimumSpacing; this.preferredSpacing = preferredSpacing; } // for specialized layouts, not used here public void addLayoutComponent(String name, Component comp) { } public void removeLayoutComponent(Component comp) { } /** * Calculates the preferred size dimensions for the specified panel given * the components in the specified parent container. */ public Dimension preferredLayoutSize(Container parent) { synchronized (parent.getTreeLock()) { // get space needed for all children Dimension space = calculateSpace(parent, true); // this container's padding Insets insets = parent.getInsets(); Dimension d = new Dimension(insets.left + space.width +insets.right, insets.top + space.height + insets.bottom); return d; } } /** * Calculates the minimum size dimensions for the specified panel given the * components in the specified parent container. */ public Dimension minimumLayoutSize(Container parent) { synchronized (parent.getTreeLock()) { // get space needed for all children Dimension space = calculateSpace(parent, false); // this container's padding Insets insets = parent.getInsets(); Dimension d = new Dimension(insets.left + space.width +insets.right, insets.top + space.height + insets.bottom); return d; } } /** * Lays out the container in the specified panel. */ public void layoutContainer(Container parent) { synchronized (parent.getTreeLock()) { // get space needed for all children (preferred) Dimension space = calculateSpace(parent, true); // this container's padding Insets insets = parent.getInsets(); // get actual space available in parent int w = parent.getWidth() - insets.left - insets.right; int h = parent.getHeight() - insets.top - insets.bottom; System.out.println("layoutContainer (parent size " + w + "," + h + ")"); // vertical centre line to layout component int y = h / 2; // starting x is left side of all components to lay out int x = (w - space.width) / 2; int nComponents = parent.getComponentCount(); for (int i = 0; i < nComponents; i++) { Component c = parent.getComponent(i); Dimension d = c.getPreferredSize(); c.setBounds(x, y - d.height / 2, d.width, d.height); x += d.width + preferredSpacing; } } } /* * Precondition: the caller has gotten the treelock. */ private Dimension calculateSpace(Container parent, boolean isPreferred) { // find total width for all components and // height of tallest component Dimension result = new Dimension(0,0); int nComponents = parent.getComponentCount(); for (int i = 0; i < nComponents; i++) { Dimension d; if (isPreferred) { d = parent.getComponent(i).getPreferredSize(); } else { d = parent.getComponent(i).getMinimumSize(); } // update the total width and height required result.width += d.width; result.height = Math.max(result.height, d.height); } // add spacing in between components if (isPreferred) { result.width += (nComponents - 1) * preferredSpacing; } else { result.width += (nComponents - 1) * minimumSpacing; } return result; } }