| CARVIEW |
|
packer
|
| Summary | Gridbag done right |
|---|---|
| Categories | None |
| License | Berkeley Software Distribution (BSD) License |
| Owner(s) | greggwon |
Packer v2.0 - Simplifying the use of GridbagLayout
The Java layout manager class, GridBagLayout (using GridBagConstraints) is inarguably the most powerful layout manager for regular, rectangularly organized layouts. Most people have a hard time using it because it requires two objects and several method calls for each Component that you wish to place into a particular container.
The org.wonderly.awt.Packer class and org.wonderly.awt.PackAs interface provide a method based execution of these steps that reduce coding and provide opportunities for code structure that explains the spacial relationships of the layed out Components.
Examples:
Here is a simple example which compares GridBagLayout and GridBagConstraint versus the org.wonderly.awt.Packer class.
Using GridBagConstraints to layout a labeled text field that expands horizontally might be coded as:
GridBagConstraints gc = new GridBagConstraints();
GridBagLayout gl = new new GridBagLayout();
Panel p = new Panel();
p.setLayout( gl );
Label l = new Label("Username:");
p.add(l);
gc.fill = GridBagConstraints.HORIZONTAL;
gc.weightx = 0;
gc.gridx = 0;
gl.setConstraints(l,gc);
TextField f = new TextField();
p.add(f);
gc.weightx = 1;
gc.gridx = 1;
gl.setConstraints(f,gc);
The org.wonderly.awt.Packer class usage that would accomplish the same thing
would be:
Panel p = new Panel();
Packer pk = new Packer(p);
Label l = new Label("Username:");
TextField f = new TextField();
pk.pack( l ).gridx(0)
.add( f ).weightx(1).gridx(1);
Or, if you, like I, dislike reusing constraints due to unexpected side
effects, we might use:
Panel p = new Panel();
Packer pk = new Packer(p);
Label l = new Label("Username:");
TextField f = new TextField();
pk.pack( l ).gridx(0);
pk.pack( f ).gridx(1).fillx();
When creating a large collection of label and field components, you
can use some patterns such as the following to simplify the addition
and reordering of components.
Panel p = new Panel();
Packer pk = new Packer(p);
// start at -1 because pre-increment makes the
// pattern shown below, work better.
int y = -1;
// start on new line and right justify label
pk.pack( new JLabel("Field 1:") ).gridx(0).gridy(++y).east();
// Put this on the same line, but fill to the right
pk.pack( new JTextField() ).gridx(1).gridy(y).fillx();
// start on new line and right justify label
pk.pack( new JLabel("Field 2:") ).gridx(0).gridy(++y).east();
// Put this on the same line, but fill to the right
pk.pack( new JTextField() ).gridx(1).gridy(y).fillx();
// start on new line and right justify label
pk.pack( new JLabel("Field 3:") ).gridx(0).gridy(++y).east();
// Put this on the same line, but fill to the right
pk.pack( new JTextField() ).gridx(1).gridy(y).fillx();
// start on new line and right justify label
pk.pack( new JLabel("Field 4:") ).gridx(0).gridy(++y).east();
// Put this on the same line, but fill to the right
pk.pack( new JComboBox() ).gridx(1).gridy(y).fillx();
// start on new line and right justify label
pk.pack( new JLabel("Field 5:") ).gridx(0).gridy(++y).east();
// Put this on the same line, but fill to the right
pk.pack( new JComboBox() ).gridx(1).gridy(y).fillx();
// start on new line and right justify label
pk.pack( new JLabel("Field 6:") ).gridx(0).gridy(++y).east();
// Put this on the same line, but fill to the right
pk.pack( new JTextField() ).gridx(1).gridy(y).fillx();
// start on new line and right justify label
pk.pack( new JLabel("Field 7:") ).gridx(0).gridy(++y).east();
// Put this on the same line, but fill to the right
pk.pack( new JTextField() ).gridx(1).gridy(y).fillx();
This example shows that you can now create a table of components that
have similar requirements for layout, and only substitute the components
that you need in each location.
So, you can see that a simple helper method can be used to create this table with even less code per row, and with some added capabilities.
Panel p = new Panel();
Packer pk = new Packer(p);
// start at -1 because pre-increment makes the
// pattern shown below, work better.
int y = -1;
y = addRow( y, pk, "Field 1:", new JTextField() );
y = addRow( y, pk, "Field 2:", new JTextField() );
y = addRow( y, pk, "Field 3:", new JTextField() );
y = addRow( y, pk, "Field 4:", new JComboBox() );
y = addRow( y, pk, "Field 5:", new JComboBox() );
y = addRow( y, pk, "Field 6:", new JTextField() );
...
int addRow( int y, Packer pk, String lab, JComponent comp ) {
JLabel l;
pk.pack( l=new JLabel(lab) ).gridx(0).gridy(++y).east();
pk.pack( comp ).gridx(1).gridy(y).fillx();
// Add this for Accessibility support
l.setLabelFor(comp);
return y;
}
This example shows some good patterns for compartmentalizing the construction
of the rows so that a single place can be changed to add a feature, such as accessiblity support. You could change the east() alignment of the
JLabel to west() in one place.
As you can see, with the use of org.wonderly.awt.Packer and the org.wonderly.awt.PackAs interface, there is less code needed for layout. The code that is needed looks a lot less cluttered to boot!
Try this applet to see how dynamic layout works. Review the example source to see how it was constructed
Jar of Classes:
The Current version of Packer is v2.0. The source files carry separate, unrelated revision related versions.
Recent additions include the PackAs.anchor(int) method which will allow the new anchor types in JSE6.0 to be used and the PackAs.link(Component) method which will allow you to clone the layout of one Component and ammend it with only the needed changes.
The jar of the Packer class and PackAs interface contains the code you need.
Documentation:
JavaDoc documentation is available too. If you'd like a ZIP file of the documentation, that is available too.
Other sources of information on layout managers and GridBagLayout include:
- Exploring the AWT Layout Managers (technical Article at Sun)
Gregg Wonderly
| Powered by CollabNet | Feedback |
FAQ |
Press |
Developer tools
© 1995 - 2007 CollabNet. CollabNet is a registered trademark of CollabNet, Inc. |
