X

Getting to Know BoxLayout

Guest Author

One of the standard layout managers that come with the Java platform isBoxLayout. This allows you to layout a single row or column of components
in a container. This may sound like a not-so-complicated layout manager,
but with the help of Box and its glue and struts, you'd think that would
be enough, but there is even more. The vertical and horizontal alignment
of the underlying components allows even more control of the positioning
of components within the container. Here, we'll look at all these aspects.

Typical Usage

BoxLayout is unlike most layout managers which just require you to create
the layout manager, and associate the layout manager with the Container.
Instead, the BoxLayout constructor requires you to pass the Container
into the constructor of the layout manager, thus having a reference to the
other component in each of them. This can be awkward sometimes, and
makes the use of the Box container more popular, since all you have to
do is ask for a horizontally or vertically laid out Box through one of
its static methods:

  Box vertical = Box.createVerticalBox();
Box horizontal = Box.createHorizontalBox();

Both are using BoxLayout under the covers, placing added components
on the proper access, depending upon direction. A vertical box
places everything into a single column, whereas a horizontal box
places everything in a row. Comparing BoxLayout (and thus Box) toGridLayout requires a quick comment. When placing a bunch of components
in a GridLayout controlled container, all the components are expected
to be the same size. With BoxLayout, that isn't the case, and the
maximum preferred size of the component is honored.

Struts and Glue

The Box class offers the creation of two supporting components, one
a strut, or fixed-size filler area, the other glue for an expandable area.
The use of these allows you to place components within a container, either
a fixed-distance apart with a strut, or a growing/shrinking area based upon
available space, with glue. The same task can be done with GridBagConstraints
and GridBagLayout, though not as easily.

To demonstrate, this first program creates a 25 pixel strut between the
top two components and a 10 pixel strut between the bottom two.

import java.awt.\*;
import javax.swing.\*;
public class VerticalBoxTest {
public static void main(String args[]) {
JFrame frame = new JFrame("Vertical Box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Box box = Box.createVerticalBox();
box.add(new Button("Top"));
box.add(Box.createVerticalStrut(25));
box.add(new Button("Middle"));
box.add(Box.createVerticalStrut(10));
box.add(new Button("Bottom"));
frame.add(box, BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setVisible(true);
}
}

Once you compile and run it, notice how the components change in size
when the window size increased or decreased. The distance between the
components remain unchanged, to match the reserved strut space. This
example uses a <code>Button</code> instead of a JButton to avoid an explanation
of component alignment until a little later.


Working with a horizontal box and glue produces similar results,
though this time the glue grows in size to take up added space, instead
of staying a fixed size, with the strut.

import java.awt.\*;
import javax.swing.\*;
public class HorizontalBoxTest {
public static void main(String args[]) {
JFrame frame = new JFrame("Horizontal Box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Box box = Box.createHorizontalBox();
box.add(Box.createHorizontalGlue());
box.add(new JButton("Left"));
box.add(new JButton("Right"));
frame.add(box, BorderLayout.NORTH);
box = Box.createHorizontalBox();
box.add(new JButton("Left"));
box.add(Box.createHorizontalGlue());
box.add(new JButton("Right"));
frame.add(box, BorderLayout.CENTER);
box = Box.createHorizontalBox();
box.add(new JButton("Left"));
box.add(new JButton("Right"));
box.add(Box.createHorizontalGlue());
frame.add(box, BorderLayout.SOUTH);
frame.setSize(300, 200);
frame.setVisible(true);
}
}


Trying not to confuse you too much, but the example is back to
using JButton components.

Alignment

Life gets interesting with Box/BoxLayout when the components within the
container are a different size or the height/width of the container is
wider than necessary for a vertical box or taller than necessary with a
horizontal one. In other words, if you have a tall column, where do
components of a different width end up? And, if you have a wide row
with components of a different height, how about them?

This is where the different alignments of a component come into play.
Each Swing component has an X-alignment setting and a Y-alignment setting
thanks to its get/setAlignmentX() and get/setAlignmentY() methods. The
range of each setting is from 0 to 1.0, inclusive, where 0 represents left
or top alignment and 1 represents right or bottom alignment, depending
upon direction of BoxLayout. There are constants available in theComponent class so you don't really need to know what the values are
for right and left alignment. However, it does help to know if you
might want something in between.

To demonstrate the right, left, center nature of different size buttons
in a vertical box, the following program creates three boxes, one each
filled with left, center, and right aligned buttons.

import java.awt.\*;
import javax.swing.\*;
public class AlignX {
private static Container makeIt(String labelChar, float alignment) {
Box box = Box.createVerticalBox();
for (int i=1; i<6; i++) {
String label = makeLabel(labelChar, i\*2);
JButton button = new JButton(label);
button.setAlignmentX(alignment);
box.add(button);
}
return box;
}
private static String makeLabel(String s, int length) {
StringBuffer buff = new StringBuffer(length);
for (int i=0; i<length; i++) {
buff.append(s);
}
return buff.toString();
}
public static void main(String args[]) {
JFrame frame = new JFrame("X Alignment");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container panel1 = makeIt("L", Component.LEFT_ALIGNMENT);
Container panel2 = makeIt("C", Component.CENTER_ALIGNMENT);
Container panel3 = makeIt("R", Component.RIGHT_ALIGNMENT);
frame.setLayout(new FlowLayout());
frame.add(panel1);
frame.add(panel2);
frame.add(panel3);
frame.pack();
frame.setVisible(true);
}
}

Now, let us mix things up a little and have one vertical box with three
buttons, one for each alignment. The screen width will be wide, to make
sure there is extra space available. Conceptually thinking, one would
expect the component with left alignment to be aligned to the left of
the container and the one with right alignment to be aligned to the
right of the container. That would be wrong though. When there are
different component alignments, they are aligned to the center of
the container. So, for left alignment, that component will have its
left edge on the invisible center line of the container. For right
alignment, it is the right edge.

Here's the program to demonstrate:

import java.awt.\*;
import javax.swing.\*;
public class AlignX2 {
public static void main(String args[]) {
JFrame frame = new JFrame("X Alignment");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Box box = Box.createVerticalBox();
JButton button = new JButton("LL");
button.setAlignmentX(Component.LEFT_ALIGNMENT);
box.add(button);
button = new JButton("CC");
button.setAlignmentX(Component.CENTER_ALIGNMENT);
box.add(button);
button = new JButton("RR");
button.setAlignmentX(Component.RIGHT_ALIGNMENT);
box.add(button);
frame.add(box, BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setVisible(true);}
}

And, the corroborating screen:

Working in the other direction has top alignment aligning the top
of the component to the imaginary center line, or in other words below
the center.

Mixing up alignments in this fashion works fine, but just takes some
getting used to, as the alignment isn't necessarily where you would
expect it to be, unless all the alignments are the same, and then it
does align to the container border, as opposed to the container center
line.

If you are still confused, feel free to modify the earlier programs
and try even more combinations of x and y alignment. Of course, if
all this baffles you, there is always GridBagLayout.

\*\*\*\*\*\*


SDN Chat: Meet the Writers of java.sun.com

Please join us in Sun's Developer Playground in Second Life on Thursday, February 14 at 10am PST to meet the writers of java.sun.com. Ed Ort, Dana Nourie, Janice Heiss, and Laureen Hudson will be inworld to discuss their adventures in writing for one of the industry's most popular websites and to share the technologies and trends they'll be keeping their eyes on in 2008. And, for the first time, SMI Press is pleased to offer attendees one of three new SMI Press books for free!


Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.