Recipe 14.2 Designing a Window Layout


Problem

The default layout isn't good enough.

Solution

Learn to deal with a layout manager.

Discussion

The container classes such as Panel have the ability to contain a series of components, but you can arrange components in a window in many ways. Rather than clutter up each container with a variety of different layout computations, the designers of the Java API used a sensible design pattern to divide the labor. A layout manager is an object that performs the layout computations for a container.[1] The AWT package has five common layout manager classes (see Table 14-1), and Swing has a few more. Plus, as we'll see in Recipe 14.18, it's not that big a deal to write your own!

[1] The LayoutManager specification is actually a Java interface rather than a class. In fact, it's two interfaces: quoting the code, interface LayoutManager2 extends LayoutManager . The differences between these two interfaces don't concern us here; we want to concentrate on using the layout managers.

Table 14-1. Layout managers

Name

Notes

Default on

FlowLayout

Flows across the container

(J)Panel, (J)Applet

BorderLayout

Five "geographic" regions

(J)Frame, (J)Window

GridLayout

Regular grid (all items same size)

None

CardLayout

Display one of many components at a time; useful for wizard-style layouts

None

GridBagLayout

Very flexible but maximally complex

None

BoxLayout (Swing)

Single row or column of components

None


Since we've broached the subject of layout management, I should mention that each component has a method called getPreferredSize( ) , which the layout managers use in deciding how and where to place components. A well-behaved component overrides this method to return something meaningful. A button or label, for example, will indicate that it wishes to be large enough to contain its text and/or icon, plus a bit of space for padding. And, if your JFrame is full of well-behaved components, you can set its size to be "just the size of all included components, plus a bit for padding," just by calling the pack( ) method, which takes no arguments. The pack( ) method goes around and asks each embedded component for its preferred size (and any nested container's getPreferredSize( ) will ask each of its components, and so on). The JFrame is then set to the best size to give the components their preferred sizes as much as is possible. If not using pack( ), you need to call the setSize( ) method, which requires either a width and a height, or a Dimension object containing this information.

A FlowLayout is the default in JPanel and Applet/JApplet . It simply lays the components out along the "normal" axis (left to right in European and English-speaking locales, right to left in Hebrew or Arabic locales, and so on, as set by the user's Locale settings). The overall collection of them is centered within the window.

The default for JFrame and JWindow is BorderLayout . This explains the problem of the single button appearing in the JFrameDemo class at the end of the previous recipe. BorderLayout divides the screen into the five areas shown in Figure 14-1. If you don't specify where to place a component, it goes into the Center. And if you place multiple components in the same region (perhaps by adding several components without specifying where to place them!), only the last one appears.

Figure 14-1. BorderLayout's five regions
figs/jcb2_1401.gif


So we can fix the previous version of the JFrameDemo in one of two ways: either we can use a FlowLayout or specify BorderLayout regions for the label and the button. The former being simpler, we'll try it out:

import java.awt.*; import javax.swing.*; public class JFrameFlowLayout extends JFrame {     public JFrameFlowLayout( ) {         Container cp = getContentPane( );         // Make sure it has a FlowLayout layoutmanager.         cp.setLayout(new FlowLayout( ));         // now add Components to "cp"...         cp.add(new JLabel("Wonderful?"));         cp.add(new JButton("Yes!"));         pack( );     }     // We need a main program to instantiate and show.     public static void main(String[] args) {         new JFrameFlowLayout( ).setVisible(true);     } }

See Also

I have not discussed the details of the advanced layouts. For an example of a dialog layout using nested panels, see the Font Chooser in Recipe 14.17. For an example of a GridBagLayout, see the GUI network client in Recipe 18.3. For more details, see the AWT and Swing books.



Java Cookbook
Java Cookbook, Second Edition
ISBN: 0596007019
EAN: 2147483647
Year: 2003
Pages: 409
Authors: Ian F Darwin

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net