[Chapter 12] 12.3 BorderLayout

#

| Chapter 12 Layout Managers |

## 12.3 BorderLayout

`BorderLayout` is a little more interesting. It tries to arrange objects in one of five geographical locations: "North," "South," "East," "West," and "Center," possibly with some padding between. `BorderLayout` is the default layout for `Window` and `Frame` 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 additional argument is passed to the layout manager when the new component is added. In this case it specifies the name of the position for the BorderLayout. Otherwise the `LayoutManager` is not consulted until it's asked to lay out the components.

The following applet sets a `BorderLayout` layout and adds our five buttons again, named for their locations; the result is shown in Figure 12.4.

#### Figure 12.4: A border layout

    import java.awt.*;

    public class Border extends java.applet.Applet {
        public void init() {
            setLayout( new java.awt.BorderLayout() );
            add( new Button("North"), "North" );
            add( new Button("East"), "East" );
            add( new Button("South"), "South" );
            add( new Button("West"), "West" );
            add( new Button("Center"), "Center" );
        }
    }

So, how exactly is the area divided up? Well, the objects at "North" and "South" get their preferred height and are expanded to fill the full area horizontally. "East" and "West" components on the other hand, get their preferred width, and are expanded to 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 12.5, 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 `Panel`. The default layout for a `Panel` 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. `Border2` illustrates this approach as shown in Figure 12.5.

#### Figure 12.5: Another border layout

    import java.awt.*;

    public class Border2 extends java.applet.Applet {
        public void init() {
            setLayout( new BorderLayout() );
            Panel p = new Panel();
            p.add(new Button("East") );
            add( p, "East" );
            p = new Panel();
            p.add(new Button("West") );
            add( p, "West" ;
            p = new Panel();
            p.add(new Button("North") );
            add( p, "North" );
            p = new Panel();
            p.add(new Button("South") );
            add(p, "South" );
            p = new Panel();
            p.add(new Button("Center") );
            add( p, "Center" );
        }
    }

In this example, we create a number of panels, put our buttons inside the panels, and put the panels into the applet, which has the `BorderLayout` manager. Now, the `Panel` for the "Center" button soaks up the extra space that comes from the `BorderLayout`. Each `Panel`'s `FlowLayout` centers the button in the panel and uses the button's preferred size. In this case, it's all a bit awkward. (This is one of the problems that `getMaximumSize()` will eventually solve.) We'll see how we could accomplish this more directly using `GridBagLayout` shortly.

Finally, this version of the applet has a lot of unused space. If we wanted, we could get rid of the extra space by resizing the applet:

    setSize( getPreferredSize() );

GridLayout |  | CardLayout