BorderLayout
is a little more interesting. It tries to arrange objects in one of
five
geographical locations, represented by
constants in the BorderLayout
class:
NORTH
, SOUTH
,
EAST
, WEST
, and
CENTER
, possibly with some padding between.
BorderLayout
is the default layout for the content
panes of JWindow
and JFrame
objects. Because each component is associated with a direction,
BorderLayout
can manage at most five components;
it squashes or stretches those components to fit its constraints. As
we’ll see in the second example, this means that you often want
to have BorderLayout
manage sets of components in
their own panels.
When we add a component to a border layout, we need to specify both
the component and the position at which to add it. To do so, we use
an overloaded version of the add( )
method that
takes an additional argument as a constraint. This specifies the name
of a position within the BorderLayout
.
The following
application sets a
BorderLayout
layout and adds our five buttons
again, named for their locations; the result is shown in Figure 16.4.
//file: Border1.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Border1 extends JPanel { public Border1( ) { setLayout(new BorderLayout( )); add(new JButton("North"), BorderLayout.NORTH); add(new JButton("South"), BorderLayout.SOUTH); add(new JButton("East"), BorderLayout.EAST); add(new JButton("West"), BorderLayout.WEST); add(new JButton("Center"), BorderLayout.CENTER); } public static void main(String[] args) { JFrame f = new JFrame("Border1"); f.addWindowListener(new WindowAdapter( ) { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setSize(300, 300); f.setLocation(200, 200); f.setContentPane(new Border1( )); f.setVisible(true); } }
So, how exactly is the area divided up?
Well, the objects at NORTH
and
SOUTH
get their preferred height and fill the
display area horizontally. EAST
and
WEST
components, on the other hand, get their
preferred width, and fill the remaining area between
NORTH
and SOUTH
vertically.
Finally, the CENTER
object takes all of the rest
of the space. As you can see in Figure 16.4,
our buttons get distorted into interesting shapes.
What if
we don’t want
BorderLayout
messing with the sizes of our
components? One option would be to put each button in its own
JPanel
. The default layout for a
JPanel
is FlowLayout
, which
respects the preferred size of components. The preferred sizes of the
panels are effectively the preferred sizes of the buttons, but if the
panels are stretched, they won’t pull their buttons with them.
The following application illustrates this approach; the result is
shown in Figure 16.5.
//file: Border2.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Border2 extends JPanel { public Border2( ) { setLayout(new BorderLayout( )); JPanel p = new JPanel( ); p.add(new JButton("North")); add(p, BorderLayout.NORTH); p = new JPanel( ); p.add(new JButton("South")); add(p, BorderLayout.SOUTH); p = new JPanel( ); p.add(new JButton("East")); add(p, BorderLayout.EAST); p = new JPanel( ); p.add(new JButton("West")); add(p, BorderLayout.WEST); p = new JPanel( ); p.add(new JButton("Center")); add(p, BorderLayout.CENTER); } public static void main(String[] args) { JFrame f = new JFrame("Border2"); f.addWindowListener(new WindowAdapter( ) { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.setSize(225, 150); f.setLocation(200, 200); f.setContentPane(new Border2( )); f.setVisible(true); } }
In this example, we create a number of panels, put our buttons inside
the panels, and put the panels into the frame window, which has the
BorderLayout
manager. Now, the
JPanel
for the CENTER
button
soaks up the extra space that comes from the
BorderLayout
. Each
JPanel
’s FlowLayout
centers the button in the panel and uses the button’s preferred
size. In this case, it’s all a bit awkward. We’ll see how
we
could
accomplish this more directly using GridBagLayout
shortly.