Previous | Next | Trail Map | Creating a User Interface | Using the JFC/Swing Packages

General Rules for Using Swing Components

This section has general information on how to write a program that contains Swing components.
Building a Swing GUI
When building a GUI that uses Swing components, you should avoid using non-Swing heavyweight components, and you should put your Swing components into a top-level Swing container. This section shows you how.
What the JComponent class provides
Most Swing components descend from JComponent, inheriting a great deal of functionality from it. This section includes code that many programs use to access common functionality.

Building a Swing GUI

The Swing package defines two types of components:

The top-level containers provide the framework in which the lightweight components exist. Specifically, a top-level Swing container provides an area in which lightweight Swing components can draw themselves. Top-level Swing containers also provide Swing features such as menu-bar placement, enhanced event handling and painting, and accessibility support.

In general, every Swing component should have a top-level Swing container above it in the container hierarchy. For example, every applet containing Swing components should be implemented as a subclass of JApplet (which is itself a subclass of Applet). Similarly, every main window that contains Swing components should be implemented with a JFrame.

Here's a picture of the GUI hierarchy for a typical Swing program that implements a window containing two buttons, a text field, and a list:

          JFrame (a top-level Swing container)
            |
           ...
            |
       content pane
            |
   +--------+--------+
   |        |        |
JButton  JButton   JPanel
                     |
                +---------+
                |         |
            JTextField  JList
                    
Here's another hierarchy figure for the same GUI, except that the GUI is in an applet running in a browser:
           ...
            |
         JApplet (a top-level Swing container)
            |
           ...
            |
       content pane
            |
   +--------+--------+
   |        |        |
JButton  JButton   JPanel
                     |
                +---------+
                |         |
            JTextField  JList

The content pane in the preceding figures is an ordinary Container that's under every top-level Swing container. A top-level Swing container is a Swing subclass of a heavyweight AWT component. Top-level Swing containers add Swing necessities -- including a content pane -- to the heavyweight AWT component.

Here's the code that constructs the GUI hierarchies shown in the preceding figures:

//Set up the JPanel, which contains the text field and list.
JPanel panel = new JPanel();
panel.setLayout(new SomeLayoutManager());
panel.add(textField);
panel.add(list);

//topLevel is an instance of JApplet or JFrame
Container contentPane = topLevel.getContentPane();
contentPane.setLayout(new AnotherLayoutManager());
contentPane.add(button1);
contentPane.add(button2);
contentPane.add(panel);

Note: You cannot add a component directly to a top-level component:
    topLevel.add(something);  //CAN'T DO THIS!!!

In general, you should avoid using heavyweight components in Swing GUIs (except for the top-level Swing container that hosts the GUI, of course). The most noticeable problem with mixing heavyweight and lightweight components is that when they overlap within a container, the heavyweight component is always drawn on top of the lightweight component. See Mixing Heavy and Light Components in The Swing Connection for more information about mixing the two types of components.

What the JComponent Class Provides

Most Swing components are implemented as subclasses of the JComponent(in the API reference documentation) class, which inherits from the Container(in the API reference documentation) class. From JComponent, Swing components inherit the following functionality:
Borders.
Using the setBorder method, you can specify the border that a component displays around its edges. You can specify that a component have extra space around its edges using an EmptyBorder instance. See the BorderFactory(in the API reference documentation) specification and Understanding Borders (an article in The Swing Connection) for more information.

Double buffering.
Double buffering can improve the appearance of a frequently changing component. Now you don't have to write the double buffering code -- Swing provides it for you. By default, Swing components are double buffered. By invoking setDoubleBuffered(false) on a component, you turn off its double buffering.

Tool tips.
By specifying a string with the setToolTipText method, you can provide help to users of a component. When the cursor pauses over the component, the specified string is displayed in a small window that appears near the component. See How to Use Tool Tips for more information.

Keyboard navigation.
Using the registerKeyboardAction method, you can enable the user to use the keyboard, instead of the mouse, to maneuver through the GUI

Note: Some classes provide convenience methods for keyboard actions. For example, AbstractButton provides setMnemonic, which lets you specify the character that, in combination with a look-and-feel-specific modifier key, causes the button's action to be performed. See How to Use Buttons for an example of using mnemonics in buttons.
The combination of character and modifier keys that the user must press to start an action is represented by a KeyStroke(in the API reference documentation) object. The resulting action event is handled by an ActionListener(in the Creating a User Interface trail) object. Each keyboard action works under exactly one of two conditions: either when the actual component has the focus or when any component in its containing window has the focus.

Properties.
With the putProperty method, you can associate one or more properties (name/object pairs) with any JComponent. For example, a layout manager might use properties to associate a constraints object with each JComponent it manages. You put and get properties using the putClientProperty and getClientProperty methods.

Application-wide pluggable look and feel.
Each Java runtime has a UIManager(in the API reference documentation) object that determines the look and feel of that runtime's Swing components. Subject to security restrictions, you can choose the look and feel used by all Swing components by invoking the UIManager.setLookAndFeel method. Behind the scenes, each JComponent object has a corresponding ComponentUI object that performs all the drawing, event handling, size determination, and so on for that JComponent.

Support for layout.
With methods such as setPreferredSize, setMinimumSize, setMaximumSize, setAlignmentX, and setAlignmentY, you can specify layout constraints without having to write your own component.

Support for accessibility.
[PENDING: describe]

Support for localization.
[PENDING: describe]


Previous | Next | Trail Map | Creating a User Interface | Using the JFC/Swing Packages