 |
Home | Changes | Index | Search | Go
GridBagLayout is a powerful layout manager that has been a part of AWT since Java 1.0. It is the most powerful of the layout managers included with AWT.
The upside of GridBagLayout is its flexibility; it is theoretically capable of building any layout you could sanely want to create. The downside of GridBagLayout is that it is extremely verbose and can be quite tedious and error-prone to use manually. My example requires an average of three to four lines of Java code per component. No XML or other markup language is used.
As of Java 1.4, it supports bidirectional locales. It does not appear to have any notion of a text baseline or system-specific whitespace (someone correct me if I'm wrong).
GridBagLayout divides the container into rows and columns. Rows and columns are assigned weights based on the components that are added. Rows and columns with a weight of zero are sized to the largest components preferred size. The remaining space is divided such that rows and columns with equal weights have equal widths or heights, those with twice as much weight have twice the size.
For example, a row has three buttons. Two have weight one, one has weight two. The button of weight two takes up 50% of the container's width, while each button of weight one takes up 25% of the container's width.
Components may span multiple rows and columns.
A GridBagConstraints object accepts the parameters for a component's placement (weight, column spanning). It is then passed as the second parameter to Container.add().
The Layout Manager Showdown example code:
import java.awt.*;
import javax.swing.*;
public class Layout {
public static void main(String args[]) {
JFrame frame;
Container c;
GridBagLayout layout;
GridBagConstraints constraints;
frame = new JFrame("Address Book Demo");
c = frame.getContentPane();
layout = new GridBagLayout();
constraints = new GridBagConstraints();
constraints.gridwidth = 1;
constraints.weightx = 0;
constraints.weighty = 0;
constraints.anchor = GridBagConstraints.EAST;
constraints.fill = GridBagConstraints.BOTH;
c.setLayout(layout);
constraints.weightx = 1;
constraints.weighty = 1;
constraints.gridheight = 10;
c.add(new JScrollPane(new JList(new String[] {"Bunny, Bugs", "Cat, Sylvester", "Coyote, Wile E.", "Devil, Tasmanian", "Duck, Daffy", "Fudd, Elmer", "Le Pew, Pepe", "Martian, Marvin"})), constraints);
constraints.weightx = 0;
constraints.weighty = 0;
constraints.gridheight = 1;
c.add(new JLabel("Last Name"), constraints);
constraints.weightx = 1;
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField("Martian"), constraints);
constraints.weightx = 0;
constraints.fill = GridBagConstraints.NONE;
c.add(new JLabel("First Name"), constraints);
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.weightx = 1;
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField("Marvin"), constraints);
constraints.gridwidth = 1;
constraints.weightx = 0;
constraints.fill = GridBagConstraints.NONE;
c.add(new JLabel("Phone"), constraints);
constraints.weightx = 1;
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField("805-123-4567"), constraints);
constraints.weightx = 0;
constraints.fill = GridBagConstraints.NONE;
c.add(new JLabel("Email"), constraints);
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.weightx = 1;
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField("marvin@wb.com"), constraints);
constraints.gridwidth = 1;
constraints.weightx = 0;
constraints.fill = GridBagConstraints.NONE;
c.add(new JLabel("Address 1"), constraints);
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.weightx = 1;
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField("1001001010101 Martian Way"), constraints);
constraints.gridwidth = 1;
constraints.weightx = 0;
constraints.fill = GridBagConstraints.NONE;
c.add(new JLabel("Address 2"), constraints);
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.weightx = 1;
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField("Suite 10111011"), constraints);
constraints.gridwidth = 1;
constraints.weightx = 0;
constraints.fill = GridBagConstraints.NONE;
c.add(new JLabel("City"), constraints);
constraints.weightx = 1;
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField("Ventura"), constraints);
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.fill = GridBagConstraints.BOTH;
c.add(new JLabel(), constraints);
constraints.gridwidth = 1;
constraints.weightx = 0;
constraints.fill = GridBagConstraints.NONE;
c.add(new JLabel("State"), constraints);
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField("CA"), constraints);
constraints.fill = GridBagConstraints.NONE;
c.add(new JLabel("Postal Code"), constraints);
constraints.gridwidth = GridBagConstraints.REMAINDER;
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField("93001"), constraints);
constraints.gridwidth = 1;
constraints.fill = GridBagConstraints.NONE;
c.add(new JLabel("Country"), constraints);
constraints.fill = GridBagConstraints.BOTH;
c.add(new JTextField(), constraints);
constraints.gridwidth = GridBagConstraints.REMAINDER;
c.add(new JLabel(""), constraints);
JPanel buttons = createButtonPanel();
c.add(buttons, constraints);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
static JPanel createButtonPanel() {
GridBagLayout layout = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
JPanel panel = new JPanel();
panel.setLayout(layout);
c.weightx = 0;
c.weighty = 0;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.CENTER;
panel.add(new JButton("New"), c);
panel.add(new JButton("Delete"), c);
panel.add(new JButton("Edit"), c);
panel.add(new JButton("Save"), c);
panel.add(new JButton("Cancel"), c);
return panel;
}
}
Notes:
Unlike the example screenshot, the "First Name", "Email", and "Postal Code" fields are aligned with each other. I decided that the code was verbose enough without copying this detail. (It has also been argued that this was a mistake in the original example.)
The row of buttons is implemented as a nested JPanel, also laid out with GridBagLayout.
|