2.4. Containers and Containment
Table 2-1 and Table 2-2 listed the GUI components available in the AWT and Swing toolkits. In order to create a graphical user interface, however, these individual components must be arranged within some kind of container. A container is a component that can contain other components. All containers inherit from the java.awt.Container base class, which itself inherits from java.awt.Component.
Main application windows and dialog boxes are commonly used containers. Each provides a window within which GUI components can be arranged to create a user interface. A graphical application does not usually arrange all its components directly within a window or dialog box, however. Instead, an application typically uses containers nested within other containers. For example, a dialog box that contains two columns of text input fields above a row of push buttons might use three separate containers, one for each column of text fields and one for the row of push buttons. Then the dialog box container contains only these three containers, instead of the full set of text fields and push buttons.
Some kinds of containers display their children in very specific ways, while others have restrictions on the number or type of components they can display. Some other containers are generic, so they can contain any number of children, arranged in any way. A generic container uses a layout manager to specify how its children should be arranged (as we'll discuss in the next section).
Table 2-3 lists the containers provided by AWT (in the java.awt package), and Table 2-4 lists the additional containers provided by Swing (in javax.swing). Menus and menu bars, such as javax.swing.JMenuBar and javax.swing.JPopupMenu, are containers. Because of their highly specialized use, however, I have listed them in the earlier tables of components. Also, the JComponent class extends java.awt.Container, which means that all Swing components are actually containers. In practice, however, they are not used this way; only the Swing classes listed in Table 2-4 are typically used as containers.
Table 2-3. AWT Containers
Table 2-4. Swing Containers
When building a graphical user interface, you must create your components, create the containers that will hold those components, and then add the components to the containers. You do this with one of the add() methods defined by java.awt.Container. In its simplest form, this process looks like this:
JButton b = new JButton("Push Me"); JPanel p = new JPanel(); p.add(b);
There are other versions of the add() method as well. In addition to specifying the component to add, you may also specify a string or an object as a constraint. The container may use this constraint object as a hint that tells it how the component should be arranged in the container. In practice, containers do not use the constraint directly, but pass it on to a layout manager, as we'll discuss shortly.
In Swing, the top-level containers JFrame, JDialog, JInternalFrame, JWindow, and JApplet are used slightly differently than containers such as JPanel, JSplitPane, and JTabbedPane.
I've said that all Swing components extend JComponent. JFrame, JInternalFrame, JDialog, JWindow, and JApplet are actually exceptions to this rule. These top-level Swing containers extend their corresponding AWT containers: Frame, Dialog, Window, and java.applet.Applet. Because these container classes do not extend JComponent, they do not inherit the Swing-specific features of JComponent.
Instead, when you create a JFrame, JInternalFrame, JDialog, JWindow, or JApplet container, the container automatically creates a single child for itself. The child is a JRootPane container. JRootPane does extend JComponent, and it is this automatically created JRootPane that will hold all of the components that are placed in the container. You cannot add children directly to the top-level container. Instead, you add them to the content pane of the JRootPane. All Swing containers that use a JRootPane implement the RootPaneContainer interface. This interface defines the getContentPane() method, which returns the container that you should use. This is not as confusing as it sounds. In practice, your code looks like this:
JButton b = new JButton("Press Me"); // Create a button JFrame f = new JFrame("Test Application"); // Create a window to display it f.getContentPane().add(b); // Add the button to the window
By default, getContentPane() returns a JPanel container, but you can override this default by creating a container of your own and passing it to setContentPane().
The JRootPane container is a complex one; it contains a number of children in addition to the content pane container. These children support features such as pop-up menus and are primarily for internal use by Swing. One notable and commonly used feature of JRootPane, however, is that it displays a JMenuBar passed to its setJMenuBar() method. (In AWT, you specify a MenuBar for a Frame by calling the setMenuBar() method of Frame.)
Copyright © 2001 O'Reilly & Associates. All rights reserved.