The most complicated layout manager, that gives you fine control over
placement of subcomponents. You position them on a rough grid and the layout
manager snuggles them up to each other. You can specify margins for each Component,
and which side/corner of its cell it should squeeze up to. The most puzzling
parameter is weightx (weighty) which controls which cells grow when the entire
layout acquires more real estate. 0 means no growth. The growth algorithm works
like this. First it searches each column for the biggest desired growth. This
becomes the desired growth for that column. Then the extra real estate
apportioned to the columns relative to the growth weights. The growth weights
need not be normalised percentages, but they could be. weighty works in a
similar way. Peter Haggar has written a most excellent tutorial.
Typical Use
Container contentpane = jframe.getContentpane();
contentpane.setLayout ( new GridBagLayout() );
contentPane.add( myPanel,
new GridBagConstraints(
0, 0 , 1, 1,
0.0, 0.0 ,
GridBagConstraints.CENTER,
GridBagConstraints.BOTH,
new Insets( 5 , 12, 11, 12),
0, 0 ) );
GridBagConstraints Fields
What are all those fields in the GridBagConstraints
for? The best way to find out is just to experiment, possibly using GridBagger.
Here are some rough hints.
| Field |
Purpose |
| gridx |
column number. First column is column 0. It is ok to skip columns to leave
room to add stuff later. They won't take up space. |
| gridy |
row number. Top row is row 0. It is ok to skip rows. |
| gridwidth |
How many cells wide the Component is. May not be
0. |
| gridheight |
How many cells tall the Component is. May not be
0. |
| weightx |
What percentage of the extra width in the container should this Component
take for its growth? Percentages don't have to add up to 100. |
| weightx |
What percentage of the extra height in the container should this Component
take for its growth? Percentages don't have to add up to 100. |
| anchor |
Where you want your Component to rest in its
containing box. By default it is GridBagConstraints. CENTER.
possibilities are: CENTER, NORTH,
NORTHEAST, EAST, SOUTHEAST,
SOUTH, SOUTHWEST, WEST,
and NORTHWEST. |
| fill |
GridBagConstraints.NONE
= don't grow the Component even if its allotted
space is bigger than he Component. VERTICAL=grow
the Component vertically to take up extra height. HORIZONTAL=grow
the Component horizontally to take up extra width. BOTH=grow
both vertically and horizontally. |
| ipadx |
How much wider you want your Component to be
than it would be normally. Measured in pixels. |
| ipady |
How much taller you want your Component to be
than it would be normally. Measured in pixels. |
| insets |
new Insets
( 0
, 0
, 0
, 0
) The minimum amount of white space you demand
around your Component. Measured in pixels. |
If your GridBagLayout does not work, here are some things to check:
-
Did you remember your setLayout? If you did not,
you are using the default FlowLayout.
-
Do you have two Components in the same grid square?
-
Did you have any setBounds or setLocation
calls on the Components? These are not needed, and
will sometimes interfere.
-
Did you remember to setConstraints or add
( Component, Constraints) for every Component?
-
Did you add Component to a unrelated JPanel.
This often happens when you cut and paste code.
-
Did you use the GridBagConstraints object you
intended for each Component? You may be juggling
several of them at once.
-
Did you remember to add the Component to the Container?
-
It is ok to use the same GridBagConstraints model
object for two different squares and modify the fields for the second Component.
Those changes won't affect the first Components so
long as you did a setConstraints (which snapshots/clones/copies
the Constraints before you made the changes.
-
Did you remember to set gridwidth and gridwidth
to a non-zero value? fill = GridBagConstraints.BOTH;
is not sufficient no make Components grow to fill
the space.
Here is my approach to writing GridBagLayouts:
-
Draw a crude overall diagram, such as this one from my Quoter Amanuensis:
// Applet GridBag:
// 0 1
// --------title-------- 0
// --------raw---------- 1
// -------cooked-------- 2
// Charset Clear Convert 3
// target 4
// trim 5
// -----instructions----- 6
-
Label it with GridBagLayout co-ordinates.
-
Get the gridx, gridy, gridheight and gridwidth parms right.
-
Set your various alignment parameters, both within the Components
and within the GridBagLayout's anchor.
-
If some Components are too small, stretch with fill.
-
Put some ipadx and ipady around buttons to plumpen them up. This does not
request more white space the way the Insets do, this leaves some room for the
component itself to grow in. You would typically use it for a JLabel
to account for the fact later setTexts might need a larger label. You want to
leave room so the whole layout does not adjust every time you setText to a
longer value. ipadx is the padding added to either end measured in pixels. It
works by setting the adding ipadx * 2 to the mimimum
width.
-
Fine tune with insets to get the spacing right. Focus at first on getting the
insets for the outer margins, then spacing between Components.
-
Fiddle with weightx and weighty so that your layout still looks good when you
grow or shrink it.
-
Ask your artist lover to look at the design and tell you where it needs
adjustment. Unfortunately mine left a decade ago, so my designs look quite
wooden.
When using GridBagLayout in Swing there are a couple
of tricks: You can't do a setLayout on your JApplet
directly. You must do it on the associated contentpane Container.
Similarly you don't add Components to the JApplet;
you add them to the associated Container. e.g.
this.setLayout( gridBagLayout );
this.add( aButton, constraints );
becomes:
Container contentpane = this.getContentPane();
contentpane.setLayout(gridBagLayout );
contentpane.add(aButton, constraints);