Taming the GridBagLayout
Of the standard layout managers of the Java SDK, the GridBagLayout
is the most useful one, but its complexity has also been known to strike
fear in the hearts of programmers. Part of the complexity lies in
the tedium
of setting up the grid bag constraints.
Consider for example the program in http://java.sun.com/docs/books/tutorial/uiswing/events/example-swing/ContainerEventDemo.java.
(To run the program, click here
[with a Java 2 enabled browser, of course]).
Can you figure out from the init() method why the grid bag
constraints
result in the given layout?
There are two problems with this code.
- The RELATIVE/REMAINDER approach is confusing. Using gridx/gridy/gridwidth/gridheight
is easier to understand, particularly if you are familiar with HTML
tables.
- The code uses a single GridBagConstraints object,
setting
and unsetting various values. It is confusing to keep track of the
settings.
For example, was it really intended that the buttons are stretched
horizontally,
or did the programmer just forget to turn off the BOTH
setting for
the fill constraint?
Some programmers make a new GridBagConstraints object for
each component
and populate it with the non-default settings. That's easier to read,
but
the code is quite bloated. Here
is a typical example.
What the world needs is a more convenient method of setting the grid
bag
constraints. I developed a convenience class GBC that solves
this
problem. Here is a usage example that produces the same layout as the
one
from the Java tutorial:
contentPane.add(scrollPane,
new GBC(0, 0)
.setSpan(2, 1)
.setFill(GBC.BOTH)
.setWeight(0, 1.0));
contentPane.add(clearButton,
new GBC(0, 1)
.setSpan(2, 1));
contentPane.add(addButton,
new GBC(0, 2)
.setWeight(1.0, 0));
contentPane.add(removeButton,
new GBC(1, 2)
.setWeight(1.0, 0));
contentPane.add(buttonPanel,
new GBC(0, 3)
.setFill(GBC.BOTH)
.setSpan(2, 1)
.setWeight(0, 1.0));
As you can see, the component positions and the various constraints are
easy
to spot. (Keep in mind that the grid bag coordinates are x/y values and
not
row/column values.)
The GBC helper class uses two tricks:
- It extends the GridBagConstraints class. Therefore, you can
supply
the GBC object to the add call. And you can use GBC
instead of GridBagConstraints as a prefix for those pesky
constant
names.
- The various set methods return the this
reference
so that they can be conveniently chained.
None of this is rocket science, but I think it is a clean and useful
mechanism
that should make the GridBagLayout less scary.
Download GBC.java.