Previous | Next | Trail Map | Creating a GUI with JFC/Swing | Swing Features and Concepts

Layout Management

The following figures show the GUIs of five programs, each of which displays five buttons. The buttons are identical, and the code for the programs is almost identical. So why do they look so different? Because they use different layout managers to control the size and position of the buttons.
Some standard layout managers
Layout management is the process of determining the size and position of components. By default, each container has a layout manager -- an object that performs layout management for the components within the container. Components can provide size and alignment hints to layout managers, but layout managers have the final say on the components' size and position.

The Java platform supplies five commonly used layout managers: BorderLayout, BoxLayout, FlowLayout, GridBagLayout, and GridLayout. These layout managers are designed for displaying multiple components at once, and are shown in the preceding figure. A sixth provided class, CardLayout, is a special-purpose layout manager used in combination with other layout managers. You can find details about each of these six layout managers, including hints for choosing the appropriate one, in Using Layout Managers(in the Creating a User Interface trail).

Whenever you use the add method to put a component in a container, you must take the container's layout manager into account. Some layout managers such as BorderLayout require you to specify the component's relative position in the container, using an extra argument to the add method. Occasionally, a layout manager such as GridBagLayout requires elaborate setup procedures. Many layout managers, however, simply place components based on the order they were added to their container.

All this probably sounds more complicated than it is. You can usually either copy code from our examples in Using the Swing Components(in the Creating a User Interface trail) or look up the individual layout manager in Using Layout Managers(in the Creating a User Interface trail). Generally, you only ever set the layout manager of two types of containers: content panes (which use BorderLayout by default) and JPanels (which use FlowLayout by default).

The rest of this section discusses some of the common layout tasks:

Setting the Layout Manager

You can easily change the layout manager that a container uses. Just invoke the container's setLayout method. For example, here's the code that makes a panel use BorderLayout:
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());

Although we recommend that you use layout managers, you can perform layout without them. By setting a container's layout property to null, you make the container use no layout manager. With this scheme, called absolute positioning, you must specify the size and position of every component within that container. One drawback of absolute positioning is that it doesn't adjust well when the top-level container is resized. Also, absolute positioning doesn't adjust well to differences between users and systems, such as different font sizes.

Providing Hints about a Component

Sometimes you need to customize the size hints that a component provides to its container's layout manager, so that the component will be laid out well. You do this by specifying the minimum, preferred, and maximum sizes of the component. You can either invoke the component's size hint setter methods -- setMinimumSize, setPreferredSize, and setMaximumSize -- or you can create a subclass of the component that overrides the appropriate getter methods -- getMinimumSize, getPreferredSize, and getMaximumSize. Currently, the only layout manager in the Java platform that pays attention to a component's requested maximum size is BoxLayout.

Besides providing size hints, you can also provide alignment hints. For example, you can specify that the top edges of two components should be aligned. You set alignment hints either by invoking the component's setAlignmentX and setAlignmentY methods, or by overriding the component's getAlignmentX and getAlignmentY methods. Currently, BoxLayout is the only layout manager that pays attention to alignment hints.

Putting Space Between Components

Three factors influence the amount of space between visible components in a container:
The layout manager
Some layout managers automatically put space between components; others don't. Some let you specify the amount of space between components. See Laying Out Components within a Container(in the Creating a User Interface trail) for information about spacing support in each layout manager.
Invisible components
You can create lightweight components tha perform no drawing, but that can take up space in the GUI. Often, you use invisible components in containers controlled by BoxLayout. See How to Use BoxLayout(in the Creating a User Interface trail) for examples of using invisible components.
Empty borders
No matter what the layout manager, you can affect the apparent amount of space between components by adding empty borders to components. The best candidates for empty borders are components that typically have no default border, such as panels and labels. Some other components, such as scroll panes, don't work well with borders in some look-and-feel implementations, due to the way their drawing code is implemented. [PENDING: check] For information about borders, see How to Use Borders(in the Creating a User Interface trail).

How Layout Management Occurs

Here's an example of a layout management sequence for a frame (JFrame).
  1. After the GUI is constructed, the pack method is invoked on the JFrame. This specifies that the frame should be at its preferred size.

  2. To find the frame's preferred size, the frame's layout manager adds the size of the frame's edges to the preferred size of the component directly contained by the frame. This is the sum of the preferred size of the frame's content pane, plus the size of the frame's menu bar, if any.

  3. The content pane's layout manager is responsible for figuring out the content pane's preferred size. By default, this layout manager is a BorderLayout object. However, let's assume that we replace it with a GridLayout object that's set up to create two columns, as in the bottom right of the preceding snapshot. The interesting thing about grid layout is that it forces all components to be the same size, and it tries to make them as wide as the widest component's preferred width and as high as highest one's preferred height.

    First, the grid layout manager queries the content pane for its insets -- the size of the content pane's border, if any. Next, the grid layout manager queries each component in the content pane for its preferred size, noting the largest preferred width and largest preferred height. Then it calculates the content pane's preferred size.

  4. When each button is asked for its preferred size, the button first checks whether the user specified a preferred size. If so, it reports that size. If not, it queries its look and feel for the preferred size.

The end result is that to determine the best size for the frame, the system determines the sizes of the containers at the bottom of the containment hierarchy. These sizes then percolate up the containment hierarchy, eventually determining the frame's total size. Similar calculations occur when the frame is resized.

For more information about layout, see Laying Out Components Within a Container(in the Creating a User Interface trail).


Previous | Next | Trail Map | Creating a GUI with JFC/Swing | Swing Features and Concepts