Commit e7aad4f3 authored by Daniel Vogel's avatar Daniel Vogel

layout demo code

parent 78e6f022
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 DemoFormLayout extends JFrame {
public static void main(String[] args) {
DemoFormLayout demo = new DemoFormLayout();
}
DemoFormLayout() {
this.setSize(400, 150);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// layout
this.setLayout(new FormLayout(10, 10));
// add first pair
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);
// add second pair
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);
this.setVisible(true);
}
void debugBorder(JComponent c) {
// try uncommenting this
// c.setBorder(BorderFactory.createLineBorder(Color.black));
}
}
/**
* A layout manager that arranges components in a double column. In most cases
* the left column will hold a label and the right column will hold a component
* the user can manipulate. Preferred component sizes are respected as much as
* possible. Components in the left column are right justified; components in
* the right column are left justified.
*
* @author Byron Weber Becker
*/
class FormLayout implements LayoutManager {
private int hGap = 8;
private int vGap = 8;
/** Construct a new FormLayout object. */
public FormLayout() {
super();
}
/**
* Construct a new FormLayout object.
*
* @param hGap
* the number of hortizontal pixels between components
* @param vGap
* the number of vertical pixels between components
*/
public FormLayout(int hGap, int vGap) {
super();
this.hGap = hGap;
this.vGap = vGap;
}
/**
* Adds the specified component with the specified name to the layout.
*
* @param name
* the component name
* @param comp
* the component to be added
*/
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) {
}
/**
* 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) {
synchronized (parent.getTreeLock()) {
ColDims cd = colDims(parent, true);
Insets insets = parent.getInsets();
Dimension d = new Dimension(cd.left + cd.right + insets.left
+ insets.right, cd.height + insets.top + insets.bottom);
return d;
}
}
/*
* Precondition: the caller has gotten the treelock. preferred = true for
* preferred sizes; false for minimum sizes
*/
private ColDims colDims(Container parent, boolean preferred) {
// ColDims: left col width, right col width, height of all rows
ColDims cd = new ColDims();
int nComponents = parent.getComponentCount();
// step through rows (every other component)
for (int i = 1; i < nComponents; i += 2) {
Component left = parent.getComponent(i - 1);
Component right = parent.getComponent(i);
Dimension dLeft;
Dimension dRight;
if (preferred) {
dLeft = left.getPreferredSize();
dRight = right.getPreferredSize();
} else {
dLeft = left.getMinimumSize();
dRight = right.getMinimumSize();
}
cd.left = (int) Math.max(cd.left, dLeft.width);
cd.right = (int) Math.max(cd.right, dRight.width);
cd.height += (int) Math.max(dLeft.height, dRight.height);
cd.height += this.vGap;
}
// edge case (odd number of components...)
if (nComponents % 2 == 1) { // get the last one on the left
Component left = parent.getComponent(nComponents - 1);
Dimension dLeft;
if (preferred) {
dLeft = left.getPreferredSize();
} else {
dLeft = left.getMinimumSize();
}
cd.left = (int) Math.max(cd.left, dLeft.width);
cd.height += dLeft.height + this.vGap;
}
cd.left += this.hGap / 2;
cd.right += this.hGap / 2;
return cd;
}
/**
* 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) {
synchronized (parent.getTreeLock()) {
ColDims cd = colDims(parent, false);
Insets insets = parent.getInsets();
Dimension d = new Dimension(cd.left + cd.right + insets.left
+ insets.right, cd.height + insets.top + insets.bottom);
return d;
}
}
/**
* Lays out the container in the specified panel.
*
* @param parent
* the component which needs to be laid out
*/
public void layoutContainer(Container parent) {
Insets insets = parent.getInsets();
synchronized (parent.getTreeLock()) {
ColDims cd = this.colDims(parent, true);
int desiredWidth = cd.left + cd.right + insets.left + insets.right;
double widthScale = Math.min(1.0, parent.getWidth()
/ (double) desiredWidth);
double heightScale = Math.min(1.0, parent.getHeight()
/ (double) cd.height);
double scale = Math.min(widthScale, heightScale);
// System.out.println("FormLayout.layoutContainer: widthScale = " +
// widthScale + "; heightScale = " + heightScale);
int midPt = (int) (((cd.left + insets.left + this.hGap) / (double) (cd.left
+ cd.right + insets.left + insets.right + hGap)) * parent
.getWidth());
int top = insets.top + this.vGap;
int nComponents = parent.getComponentCount();
for (int i = 1; i < nComponents; i += 2) {
Component left = parent.getComponent(i - 1);
Component right = parent.getComponent(i);
Dimension lDim = left.getPreferredSize();
Dimension rDim = right.getPreferredSize();
int rowHeight = (int) (Math.max(lDim.height, rDim.height) * heightScale);
// scale left side, if necessary; then position
if (lDim.width > desiredWidth || lDim.height > rowHeight) {
lDim.width = (int) (lDim.width * scale);
lDim.height = (int) (lDim.height * scale);
}
left.setBounds((midPt - lDim.width - this.hGap / 2), top,
lDim.width, lDim.height);
// scale right side, if necessary; then position
if (rDim.width > desiredWidth || rDim.height > rowHeight) {
rDim.width = (int) (rDim.width * scale);
rDim.height = (int) (rDim.height * scale);
}
right.setBounds(midPt + this.hGap / 2, top, rDim.width,
rDim.height);
top = top + rowHeight + this.vGap;
}
if (nComponents % 2 == 1) { // odd number of components -- get the
// last one on the left
Component left = parent.getComponent(nComponents - 1);
Dimension lDim = left.getPreferredSize();
lDim.width = (int) (lDim.width * scale);
lDim.height = (int) (lDim.height * scale);
left.setBounds((midPt - lDim.width - this.hGap / 2), top,
lDim.width, lDim.height);
}
}
}
private static class ColDims {
int left = 0;
int right = 0;
int height = 0;
}
}
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.SpringLayout;
import java.awt.LayoutManager;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/* Demonstrate various layout managers available in Java,
* including defining your own layout manager.
*
* @author Byron Weber Becker
*/
public class LayoutDemo {
public static void main(String[] args) {
// These are stacked bottom to top, so put the first one
// to be discussed last.
new LayoutFrame("RandomLayout", new DemoRandomLayout());
new LayoutFrame("SpringLayout", new DemoSpringLayout());
new LayoutFrame("GridBagLayout", new DemoGridBagLayout());
new LayoutFrame("BorderLayout", new DemoBorderLayout());
new LayoutFrame("BoxLayout3", new DemoBoxLayout3());
new LayoutFrame("BoxLayout2", new DemoBoxLayout2());
new LayoutFrame("BoxLayout1", new DemoBoxLayout1());
new LayoutFrame("GridLayout", new DemoGridLayout());
new LayoutFrame("FlowLayout", new DemoFlowLayout());
new LayoutFrame("NullLayout", new DemoNullLayout());
}
}
class LayoutFrame extends JFrame {
private static int xPos = 10;
private static int yPos = 10;
private static final int OFFSET = 50;
public LayoutFrame(String title, JPanel contents) {
super(title);
this.setContentPane(contents);
this.setSize(300, 130);
// set this to keep the JFrame from shrinking too small
//this.setMinimumSize(new Dimension(150, 100));
this.setLocation(xPos, yPos);
xPos += OFFSET;
yPos += OFFSET;
//this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
// give positions and sizes for all widgets
class DemoNullLayout extends JPanel {
public DemoNullLayout() {
super();
this.setBackground(Color.DARK_GRAY);
this.setLayout(null);
JButton b1 = new JButton("Button1");
JButton b2 = new JButton("Button2");
b1.setBounds(10, 20, 150, 50); // x, y, width, height
b2.setBounds(40, 60, 100, 30);
this.add(b2);
this.add(b1);
}
}
class DemoFlowLayout extends JPanel {
public DemoFlowLayout() {
super();
this.setBackground(Color.DARK_GRAY);
// note also FlowLayout(int alignment, int horizontalSpace, int verticalSpace);
this.setLayout(new FlowLayout());
this.add(new JButton(" One "));
this.add(new JTextField(" Two ", 10));
this.add(new JButton(" Three "));
this.add(new JButton(" Four "));
}
}
class DemoGridLayout extends JPanel {
private JButton one = new JButton("One");
private JButton two = new JButton("Two");
private JButton three = new JButton("Three");
private JButton four = new JButton("Four");
private JButton five = new JButton("Five");
private JButton six = new JButton("Six");
public DemoGridLayout() {
super();
this.setBackground(Color.DARK_GRAY);
// Set the layout strategy to a grid with 2 rows and 3 columns.
GridLayout strategy = new GridLayout(2, 3);
this.setLayout(strategy);
// Add the components
// (always added in left-to-right, top-to-bottom reading order )
this.add(this.one);
this.add(this.two);
this.add(this.three);
this.add(this.four);
this.add(this.five);
this.add(this.six);
}
}
class DemoBoxLayout1 extends JPanel {
// Default behaviour of BoxLayout
public DemoBoxLayout1() {
super();
this.setBackground(Color.DARK_GRAY);
// try BoxLayout.X_AXIS as well
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.add(new JButton("One"));
this.add(new JButton("Two"));
this.add(new JTextArea("TextArea"));
this.add(new JButton("Three"));
}
}
class DemoBoxLayout2 extends JPanel {
public DemoBoxLayout2() {
super();
this.setBackground(Color.DARK_GRAY);
JTextArea ta = new JTextArea("TextArea");
// Text areas have infinite maximum size by default, so BoxLayout will
// grow it to fill all available space unless we place a limit.
ta.setMaximumSize(new Dimension(200, 150));
// now add same as DemoBoxLayout1
this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
this.add(new JButton("One"));
this.add(new JButton("Two"));
this.add(ta);
this.add(new JButton("Three"));
}
}
class DemoBoxLayout3 extends JPanel {
// Using rigid areas, struts and glue
public DemoBoxLayout3() {
super();
this.setBackground(Color.DARK_GRAY);
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.add(new JButton("One"));
this.add(Box.createRigidArea(new Dimension(0,10)));
this.add(Box.createVerticalGlue());
this.add(new JButton("Two"));
this.add(Box.createVerticalStrut(10));
this.add(new JButton("Three"));
}
}
class DemoBorderLayout extends JPanel {
public DemoBorderLayout() {
super();
this.setBackground(Color.DARK_GRAY);
this.setLayout(new BorderLayout());
this.add(new JButton("North"), BorderLayout.NORTH);
this.add(new JButton("East"), BorderLayout.EAST);
this.add(new JButton("West"), BorderLayout.WEST);
// Layouts can be nested ...
// Box is an easy-to-create JPanel with a BoxLayout
Box b = Box.createHorizontalBox();
b.add(Box.createHorizontalGlue());
b.add(new JButton("Ok"));
b.add(Box.createHorizontalStrut(20));
b.add(new JButton("Cancel"));
this.add(b, BorderLayout.SOUTH);
// nesting a previous demo panel ...
this.add(new DemoBoxLayout1(), BorderLayout.CENTER);
}
}
class DemoGridBagLayout extends JPanel {
public DemoGridBagLayout() {
super();
this.setBackground(Color.DARK_GRAY);
this.setLayout(new GridBagLayout());
// create a constraints object
GridBagConstraints gc = new GridBagConstraints();
// stretch the widget horizontally and vertically
gc.fill = GridBagConstraints.BOTH;
gc.gridwidth = 1; // 1 grid cell wide
gc.gridheight = 3; // 3 grid cells tall
gc.weightx = 0.5; // the proportion of space to give this column
gc.weighty = 0.5; // the proportion of space to give this row
this.add(new JButton("One"), gc);
// modify gc for the next widget to be added
gc.fill = GridBagConstraints.VERTICAL;
gc.gridwidth = 1;
gc.gridheight = 1;
gc.gridx = 1;
gc.gridy = 0;
gc.anchor = GridBagConstraints.WEST;
this.add(new JButton("Two"), gc);
gc.gridy = 1;
gc.anchor = GridBagConstraints.CENTER;
this.add(new JButton("Three"), gc);
gc.gridy = 2;
gc.anchor = GridBagConstraints.EAST;
this.add(new JButton("Four"), gc);
// add something spanning across the bottom
gc.fill = GridBagConstraints.HORIZONTAL;
gc.gridx = 0;
gc.gridy = 3;
gc.gridwidth = 2;
this.add(new JButton("Five"), gc);
}
}
class DemoSpringLayout extends JPanel {
private JButton b1 = new JButton("b1 - - - - ");
private JTextArea t1 = new JTextArea("t1");
private JButton b2 = new JButton("b2");
public DemoSpringLayout() {
super();
this.setBackground(Color.DARK_GRAY);
SpringLayout layout = new SpringLayout();
this.setLayout(layout);
this.add(this.b1);
this.add(this.t1);
this.add(this.b2);
// Add constraints
// constrain west side of b1 to be 10 pixels from west side of the panel
layout.putConstraint(SpringLayout.WEST, b1, 10,
SpringLayout.WEST, this);
// constrain north side of b1 to be 10 pixels from north side of the panel
layout.putConstraint(SpringLayout.NORTH, b1, 10,
SpringLayout.NORTH, this);
// constrain b2 to stay 10 pixels from left of panel
layout.putConstraint(SpringLayout.WEST, b2, 10,
SpringLayout.WEST, this);
// constrain b2 to stay 10 pixels from bottom of panel
layout.putConstraint(SpringLayout.SOUTH, b2, -10,
SpringLayout.SOUTH, this);
layout.putConstraint(SpringLayout.EAST, b2, 0,
SpringLayout.EAST, b1);
// Let the textarea grow as large as requested
t1.setMaximumSize(new Dimension(Integer.MAX_VALUE,
Integer.MAX_VALUE));
// constrain t1 to be east of the buttons and spread vertically to fill
// the entire height of the panel
layout.putConstraint(SpringLayout.WEST, t1, 10,
SpringLayout.EAST, b2);
layout.putConstraint(SpringLayout.NORTH, t1, 10,
SpringLayout.NORTH, this);
layout.putConstraint(SpringLayout.SOUTH, t1, -10,
SpringLayout.SOUTH, this);
layout.putConstraint(SpringLayout.EAST, t1, -10,
SpringLayout.EAST, this );
}
}
class DemoRandomLayout extends JPanel {
private JButton one = new JButton("One");
private JButton two = new JButton("Two");
private JButton three = new JButton("Three");
private JButton four = new JButton("Four");
private JButton five = new JButton("Five");
private JButton six = new JButton("Six");
public DemoRandomLayout() {
super();
this.setBackground(Color.DARK_GRAY);
this.setLayout(new RandomLayout());
// Add the components.
this.add(this.one);
this.add(this.two);
this.add(this.three);
this.add(this.four);
this.add(this.five);
this.add(this.six);
}
}
// a custom layout manager
class RandomLayout implements LayoutManager {
public void addLayoutComponent(String name, Component comp) {
; // no-op
}
public void layoutContainer(Container container) {
Component[] components = container.getComponents();
Dimension parentSize = container.getSize();
for (int i = 0; i < components.length; i++) {
Component c = components[i];
c.setSize(c.getPreferredSize());
int x = (int)(Math.random() * (parentSize.width - c.getWidth()));
int y = (int)(Math.random() * (parentSize.height - c.getHeight()));
c.setLocation(x, y);
}
}
public Dimension minimumLayoutSize(Container parent) {
return new Dimension(400, 300);
}
public Dimension preferredLayoutSize(Container parent) {
return this.minimumLayoutSize(parent);
}
public void removeLayoutComponent(Component comp) {
; // no-op
}
}