Swing Features and Concepts |
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. 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 size and position of those components.The Java platform supplies five commonly used layout managers:
BorderLayout
,BoxLayout
,FlowLayout
,GridBagLayout
, andGridLayout
. 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.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 asBorderLayout
, require you to specify the component's relative position in the container, using an additional argument with theadd
method. Occasionally, a layout manager such asGridBagLayout
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 or look up the individual layout manager in Using Layout Managers. Generally, you only ever set the layout manager of two types of containers: content panes (which use
BorderLayout
by default) andJPanel
s (which useFlowLayout
by default).The rest of this section discusses some of the common layout tasks:
- Setting the layout manager
- Providing hints about a component
- Putting space between components
- How layout management occurs
Setting the Layout Manager
You can easily change the layout manager that a container uses. Just invoke the container'ssetLayout
method. For example, here's the code that makes a panel useBorderLayout
: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 strategy, 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, nor does it 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 methods for setting size hints --setMinimumSize
,setPreferredSize
, andsetMaximumSize
-- or you can create a subclass of the component that overrides the appropriate getter methods --getMinimumSize
,getPreferredSize
, andgetMaximumSize
. Currently, the only layout manager in the Java platform that pays attention to a component's requested maximum size isBoxLayout
.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
andsetAlignmentY
methods, or by overriding the component'sgetAlignmentX
andgetAlignmentY
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 for information about spacing support in each layout manager.
- Invisible components
- You can create lightweight components that perform no painting, but that can take up space in the GUI. Often, you use invisible components in containers controlled by
BoxLayout
. See How to Use BoxLayout 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, because of the way their painting code is implemented. [PENDING: check] For information about borders, see How to Use Borders.
How Layout Management Occurs
Here's an example of a layout management sequence for a frame (For more information about layout, see Laying Out Components Within a Container.JFrame
).
- After the GUI is constructed, the
pack
method is invoked on theJFrame
. This specifies that the frame should be at its preferred size.
- 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.
- 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 aGridLayout
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.
- 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.
Swing Features and Concepts |