The LayoutInfo objects specify how a Widget is placed whithin
a WidgetContainer. Where the widget is placed is a matter that depends on
the WidgetContainer: for example borderContainer.add( aWidget,
BorderContainer.CENTER)
puts aWidget
at the center of
the BorderContainer. Placement will be different for a RowContainer or a
ColumnContainer. But these WidgetContainers have all one thing in common :
they all use LayoutInfo instances to control the layouts of the children
widgets. A child widget is placed in a rectangular area whithin the widget
container. If this rectangular area exactly matches the size of the child
widget, there is not much to say : the widget is simply displayed in that
area and the bounds of the widget are those of the area. Generally, the
widget container tries to adapt the size of the area to the preferred size
of the child widget so as to make everyone happy about it. But there are
situations where this is simply not possible. For example, a constant grid
(grid container) may contain children of different sizes, and the
rectangular areas where the smallest widgets are placed will be too big.
Or the window has been resized and it's bigger than needed.
In that situation, the LayoutInfo object associated with the widget (or the default layout if there no specific LayoutInfo associated with the widget) specifies how to place the widget whithin the area : top-left corner, right side, etc. Or it can tell the widget container to expand the widget so that it fits the area vertically or horizontally or both.
The LayoutInfo objects also specify parameters that are relevant even if the rectangular area where the widget container places the widget has the right size : the Insets and the Padding. We'll see shortly what these parameters mean, but it's about time we describe LayoutInfo objects in depth.
Here is what the API tells us about a LayoutInfo instance constructor
:LayoutInfo(LayoutInfo.Alignment align, LayoutInfo.FillType
fill, java.awt.Insets insets, java.awt.Dimension padding)
(the
default constructor is volontarily omitted becaused there is not much
point in using the default layout thus generated).
Here is a code sample (full source code here):
GridContainer gc = new GridContainer( 3, 3 ); gc.add( new BButton( "North" ), 1, 0, new LayoutInfo( LayoutInfo.NORTH, LayoutInfo.NONE, null, null ) ); gc.add( new BButton( "East" ), 2, 1, new LayoutInfo( LayoutInfo.EAST, LayoutInfo.NONE, null, null ) ); gc.add( new BButton( "West" ), 0, 1, new LayoutInfo( LayoutInfo.WEST, LayoutInfo.NONE, null, null ) ); gc.add( new BButton( "South" ), 1, 2, new LayoutInfo( LayoutInfo.SOUTH, LayoutInfo.NONE, null, null ) ); gc.add( new BButton( "Center" ), 1, 1, new LayoutInfo( LayoutInfo.CENTER, LayoutInfo.NONE, null, null ) ); gc.add( new BButton( "NorthEast" ), 2, 0, new LayoutInfo( LayoutInfo.NORTHEAST, LayoutInfo.NONE, null, null ) ); gc.add( new BButton( "NorthWest" ), 0, 0, new LayoutInfo( LayoutInfo.NORTHWEST, LayoutInfo.NONE, null, null ) ); gc.add( new BButton( "SouthEast" ), 2, 2, new LayoutInfo( LayoutInfo.SOUTHEAST, LayoutInfo.NONE, null, null ) ); gc.add( new BButton( "SouthWest" ), 0, 2, new LayoutInfo( LayoutInfo.SOUTHWEST, LayoutInfo.NONE, null, null ) );
If you grow the window that appear when the demo is launched, you'll see that the placement of the buttons follows the alignment parameter of the corresponding layout info object (see below).
Before resizing | After |
![]() |
![]() |
Now, let's make use of the fill type for some of the buttons, as shown in the code below:
gc.add( new BButton( "North" ), 1, 0,
new LayoutInfo( LayoutInfo.NORTH, LayoutInfo.VERTICAL, null, null ) );
gc.add( new BButton( "East" ), 2, 1,
new LayoutInfo( LayoutInfo.EAST, LayoutInfo.NONE, null, null ) );
gc.add( new BButton( "West" ), 0, 1,
new LayoutInfo( LayoutInfo.WEST, LayoutInfo.HORIZONTAL, null, null ) );
gc.add( new BButton( "South" ), 1, 2,
new LayoutInfo( LayoutInfo.SOUTH, LayoutInfo.NONE, null, null ) );
gc.add( new BButton( "Center" ), 1, 1,
new LayoutInfo( LayoutInfo.CENTER, LayoutInfo.BOTH, null, null ) );
gc.add( new BButton( "NorthEast" ), 2, 0,
new LayoutInfo( LayoutInfo.NORTHEAST, LayoutInfo.NONE, null, null ) );
gc.add( new BButton( "NorthWest" ), 0, 0,
new LayoutInfo( LayoutInfo.NORTHWEST, LayoutInfo.VERTICAL, null, null ) );
gc.add( new BButton( "SouthEast" ), 2, 2,
new LayoutInfo( LayoutInfo.SOUTHEAST, LayoutInfo.NONE, null, null ) );
gc.add( new BButton( "SouthWest" ), 0, 2,
new LayoutInfo( LayoutInfo.SOUTHWEST, LayoutInfo.HORIZONTAL, null, null ) );
and here is the result after resizing:
So far, we haven't made use of Insets nor of Paddings. That's precisely why the Insets and Padding parameters were set to null. In this case, the insets used are Insets(0,0,0,0) and for the padding Dimension(0,0). Now, let us consider the code given below, where all the buttons have the same size in the grid due to using LayoutInfo.BOTH as fill type.
gc.add( new BButton( "North" ), 1, 0, new LayoutInfo(
LayoutInfo.NORTH, LayoutInfo.BOTH, null, null ) );
etc.
The result is shown in the following picture. The buttons are packed and touch each other, a situation we most likely want to avoid in a dialog or window.
Using symetric insets like in the code below, we get a nicer result :
gc.add( new BButton( "North" ), 1, 0, new LayoutInfo(
LayoutInfo.NORTH, LayoutInfo.BOTH, new Insets( 3, 3, 3, 3 ), null )
);
etc.
Eventually we can use the Padding parameter to get either bigger buttons, like with (code here):
gc.add( new BButton( "North" ), 1, 0, new LayoutInfo(
LayoutInfo.NORTH, LayoutInfo.BOTH, new Insets( 3, 3, 3, 3 ), new
Dimension( 10, 10 ) ) );
or smaller buttons, needed for example in a tight window (code here):
gc.add( new BButton( "North" ), 1, 0, new LayoutInfo( LayoutInfo.NORTH, LayoutInfo.BOTH, new Insets( 3, 3, 3, 3 ), new Dimension( -5, -5 ) ) );
![]() |
![]() |
One last word about LayoutInfo : do not reuse a LayoutInfo object unless you're pretty sure of what you are doing. Let's have a look at the following bit of code:
gc.add( new BButton( "North" ), 1, 0, new LayoutInfo(
LayoutInfo.NORTH, LayoutInfo.VERTICAL, null, null ) );
gc.add( new
BButton( "East" ), 2, 1,new LayoutInfo( LayoutInfo.EAST, LayoutInfo.NONE,
null, null ) );
You could say that this second piece of code does the same job:
LayoutInfo layoutInfo = new LayoutInfo( LayoutInfo.NORTH,
LayoutInfo.VERTICAL, null, null );
gc.add( new BButton( "North" ),
1, 0, layoutInfo );
layoutInfo.setAlignment( LayoutInfo.EAST
);
gc.add( new BButton( "East" ), 2, 1, layoutInfo );
However, this is not the case. The add
method of the
widget containers does not store a copy of the LayoutInfo instance given
as parameter, but the instance itself. So the setAlignment
assignment also changes the alignment of the "North" button, which is not
what we wanted.