1.3 Using Swing Components

«« Previous
Next »»

➤ Using Top-Level Containers

As we mentioned before, Swing provides three generally useful top-level container classes: JFrame, JDialog, and JApplet. When using these classes, you should keep these facts in mind:
  • To appear onscreen, every GUI component must be part of a containment hierarchy. A containment hierarchy is a tree of components that has a top-level container as its root. We'll show you one in a bit.
  • Each GUI component can be contained only once. If a component is already in a container and you try to add it to another container, the component will be removed from the first container and then added to the second.
  • Each top-level container has a content pane that, generally speaking, contains (directly or indirectly) the visible components in that top-level container's GUI.
  • You can optionally add a menu bar to a top-level container. The menu bar is by convention positioned within the top-level container, but outside the content pane. Some look and feels, such as the Mac OS look and feel, give you the option of placing the menu bar in another place more appropriate for the look and feel, such as at the top of the screen.
Note: Although JInternalFrame mimics JFrame, internal frames aren't actually top-level containers.
Here's a picture of a frame created by an application. The frame contains a green menu bar (with no menus) and, in the frame's content pane, a large blank, yellow label.


You can find the entire source for this example in TopLevelDemo.java. Although the example uses a JFrame in a standalone application, the same concepts apply to JApplets and JDialogs.

Here's the containment hierarchy for this example's GUI:


As the ellipses imply, we left some details out of this diagram. We reveal the missing details a bit later. Here are the topics this section discusses:
  1. Top-Level Containers and Containment Hierarchies
  2. Adding Components to the Content Pane
  3. Adding a Menu Bar
  4. The Root Pane (a.k.a. The Missing Details)
1. Top-Level Containers and Containment Hierarchies

Each program that uses Swing components has at least one top-level container. This top-level container is the root of a containment hierarchy — the hierarchy that contains all of the Swing components that appear inside the top-level container.

As a rule, a standalone application with a Swing-based GUI has at least one containment hierarchy with a JFrame as its root. For example, if an application has one main window and two dialogs, then the application has three containment hierarchies, and thus three top-level containers. One containment hierarchy has a JFrame as its root, and each of the other two has a JDialog object as its root.

A Swing-based applet has at least one containment hierarchy, exactly one of which is rooted by a JApplet object. For example, an applet that brings up a dialog has two containment hierarchies. The components in the browser window are in a containment hierarchy rooted by a JApplet object. The dialog has a containment hierarchy rooted by a JDialog object.

2. Adding Components to the Content Pane

Here's the code that the preceding example uses to get a frame's content pane and add the yellow label to it:

frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);

As the code shows, you find the content pane of a top-level container by calling the getContentPane method. The default content pane is a simple intermediate container that inherits from JComponent, and that uses a BorderLayout as its layout manager.

It's easy to customize the content pane — setting the layout manager or adding a border, for example. However, there is one tiny gotcha. The getContentPane method returns a Container object, not a JComponent object. This means that if you want to take advantage of the content pane's JComponent features, you need to either typecast the return value or create your own component to be the content pane. Our examples generally take the second approach, since it's a little cleaner. Another approach we sometimes take is to simply add a customized component to the content pane, covering the content pane completely.

Note that the default layout manager for JPanel is FlowLayout; you'll probably want to change it.

To make a component the content pane, use the top-level container's setContentPane method. For example:

//Create a panel and add components to it.
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setBorder(someBorder);
contentPane.add(someComponent, BorderLayout.CENTER);
contentPane.add(anotherComponent, BorderLayout.PAGE_END);

topLevelContainer.setContentPane(contentPane);

Note: As a convenience, the add method and its variants, remove and setLayout have been overridden to forward to the contentPane as necessary. This means you can write

frame.add(child);
and the child will be added to the contentPane.

Note that only these three methods do this. This means that getLayout() will not return the layout set with setLayout().

3. Adding a Menu Bar

In theory, all top-level containers can hold a menu bar. In practice, however, menu bars usually appear only in frames and applets. To add a menu bar to a top-level container, create a JMenuBar object, populate it with menus, and then call setJMenuBar. The TopLevelDemo adds a menu bar to its frame with this code:

frame.setJMenuBar(greenMenuBar);

4. The Root Pane

Each top-level container relies on a reclusive intermediate container called the root pane. The root pane manages the content pane and the menu bar, along with a couple of other containers. You generally don't need to know about root panes to use Swing components. However, if you ever need to intercept mouse clicks or paint over multiple components, you should get acquainted with root panes.

Here's a list of the components that a root pane provides to a frame (and to every other top-level container):


We've already told you about the content pane and the optional menu bar. The two other components that a root pane adds are a layered pane and a glass pane. The layered pane contains the menu bar and content pane, and enables Z-ordering of other components. The glass pane is often used to intercept input events occuring over the top-level container, and can also be used to paint over multiple components.


➤ The JComponent Class

With the exception of top-level containers, all Swing components whose names begin with "J" descend from the JComponent class. For example, JPanel, JScrollPane, JButton, and JTable all inherit from JComponent. However, JFrame and JDialog don't because they implement top-level containers.

The JComponent class extends the Container class, which itself extends Component. The Component class includes everything from providing layout hints to supporting painting and events. The Container class has support for adding components to the container and laying them out. This section's API tables summarize the most often used methods of Component and Container, as well as of JComponent.

JComponent Features

The JComponent class provides the following functionality to its descendants:
  1. Tool tips
  2. Painting and borders
  3. Application-wide pluggable look and feel
  4. Custom properties
  5. Support for layout
  6. Support for accessibility
  7. Support for drag and drop
  8. Double buffering
  9. Key bindings
1. 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.

2. Painting and borders

The setBorder method allows you to specify the border that a component displays around its edges. To paint the inside of a component, override the paintComponent method.

3. Application-wide pluggable look and feel

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. Exactly which ComponentUI object is used depends on the current look and feel, which you can set using the UIManager.setLookAndFeel method.

4. Custom properties

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.

5. Support for layout

Although the Component class provides layout hint methods such as getPreferredSize and getAlignmentX, it doesn't provide any way to set these layout hints, short of creating a subclass and overriding the methods. To give you another way to set layout hints, the JComponent class adds setter methods — setMinimumSize, setMaximumSize, setAlignmentX, and setAlignmentY.

6. Support for accessibility

The JComponent class provides API and basic functionality to help assistive technologies such as screen readers get information from Swing components.

7. Support for drag and drop

The JComponent class provides API to set a component's transfer handler, which is the basis for Swing's drag and drop support.

8. Double buffering

Double buffering smooths on-screen painting.

9. Key bindings

This feature makes components react when the user presses a key on the keyboard. For example, in many look and feels when a button has the focus, typing the Space key is equivalent to a mouse click on the button. The look and feel automatically sets up the bindings between pressing and releasing the Space key and the resulting effects on the button.

The JComponent API

The JComponent class provides many new methods and inherits many methods from Component and Container. The following tables summarize the methods we use the most.

  • Customizing Component Appearance
Method
Purpose
void setBorder(Border)
Border getBorder()
Set or get the border of the component.
void setForeground(Color)
void setBackground(Color)
Set the foreground or background color for the component. The foreground is generally the color used to draw the text in a component. The background is (not surprisingly) the color of the background areas of the component, assuming that the component is opaque.
Color getForeground()
Color getBackground()
Get the foreground or background color for the component.
void setOpaque(boolean)
boolean isOpaque()
Set or get whether the component is opaque. An opaque component fills its background with its background color.
void setFont(Font)
Font getFont()
Set or get the component's font. If a font has not been set for the component, the font of its parent is returned.
void setCursor(Cursor)
Cursor getCursor()
Set or get the cursor displayed over the component and all components it contains (except for children that have their own cursor set). Example: aPanel.setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR));
  • Setting and Getting Component State
Method
Purpose
void setComponentPopupMenu(JPopupMenu)Sets the JPopupMenu for this JComponent. The UI is responsible for registering bindings and adding the necessary listeners such that the JPopupMenu will be shown at the appropriate time. When the JPopupMenu is shown depends upon the look and feel: some may show it on a mouse event, some may enable a key binding.

If popup is null, and getInheritsPopupMenu returns true, then getComponentPopupMenu will be delegated to the parent. This provides for a way to make all child components inherit the popupmenu of the parent.
void setTransferHandler(TransferHandler)
TransferHandler getTransferHandler()
Set or remove the transferHandler property. The TransferHandler supports exchanging data via cut, copy, or paste to/from a clipboard as well a drag and drop.
void setToolTipText(String)Set the text to display in a tool tip.
void setName(String)
String getName()
Set or get the name of the component. This can be useful when you need to associate text with a component that does not display text.
boolean isShowing()Determine whether the component is showing on screen. This means that the component must be visible, and it must be in a container that is visible and showing.
void setEnabled(boolean)
boolean isEnabled()
Set or get whether the component is enabled. An enabled component can respond to user input and generate events.
void setVisible(boolean) boolean isVisible() Set or get whether the component is visible. Components are initially visible, with the exception of top-level components.
  • Handling Events
Method
Purpose
void addHierarchyListener(hierarchyListener l)
void removeHierarchyListener(hierarchyListener l)
Adds or removes the specified hierarchy listener to receive hierarchy changed events from this component when the hierarchy to which this container belongs changes. If listener l is null, no exception is thrown and no action is performed.
void addMouseListener(MouseListener)
void removeMouseListener(MouseListener)
Add or remove a mouse listener to or from the component. Mouse listeners are notified when the user uses the mouse to interact with the listened-to component.
void addMouseMotionListener(MouseMotionListener)
void removeMouseMotionListener(MouseMotionListener)
Add or remove a mouse motion listener to or from the component. Mouse motion listeners are notified when the user moves the mouse within the listened-to component's bounds.
void addKeyListener(KeyListener)
void removeKeyListener(KeyListener)
Add or remove a key listener to or from the component. Key listeners are notified when the user types at the keyboard and the listened-to component has the keyboard focus.
void addComponentListener(ComponentListener)
void removeComponentListener(ComponentListener)
Add or remove a component listener to or from the component. Component listeners are notified when the listened-to component is hidden, shown, moved, or resized.
boolean contains(int, int)
boolean contains(Point)
Determine whether the specified point is within the component. The argument should be specified in terms of the component's coordinate system. The two int arguments specify x and y coordinates, respectively.
Component getComponentAt(int, int)
Component getComponentAt(Point)
Return the component that contains the specified x, y position. The top-most child component is returned in the case where components overlap. This is determined by finding the component closest to the index 0 that claims to contain the given point via Component.contains().
Component setComponentZOrder(component comp, int index) Moves the specified component to the specified z-order index in the container.

If the component is a child of some other container, it is removed from that container before being added to this container. The important difference between this method and java.awt.Container.add(Component, int) is that this method doesn't call removeNotify on the component while removing it from its previous container unless necessary and when allowed by the underlying native windowing system. This way, if the component has the keyboard focus, it maintains the focus when moved to the new position.

Note:  The z-order determines the order that components are painted. The component with the highest z-order paints first and the component with the lowest z-order paints last. Where components overlap, the component with the lower z-order paints over the component with the higher z-order.
Component getComponentZOrder(component comp) Returns the z-order index of the component inside the container. The higher a component is in the z-order hierarchy, the lower its index. The component with the lowest z-order index is painted last, above all other child components.

  • Painting Components
Method
Purpose
void repaint()
void repaint(int, int, int, int)
Request that all or part of the component be repainted. The four int arguments specify the bounds (x, y, width, height, in that order) of the rectangle to be painted.
void repaint(Rectangle)Request that the specified area within the component be repainted.
void revalidate()Request that the component and its affected containers be laid out again. You should not generally need to invoke this method unless you explicitly change a component's size/alignment hints after it's visible or change a containment hierarchy after it is visible. Always invoke repaint after revalidate.
void paintComponent(Graphics)Paint the component. Override this method to implement painting for custom components.
  • Dealing with the Containment Hierarchy
Method
Purpose
Component add(Component)
Component add(Component, int)
void add(Component, Object)
Add the specified component to this container. The one-argument version of this method adds the component to the end of the container. When present, the int argument indicates the new component's position within the container. When present, the Object argument provides layout constraints to the current layout manager.
void remove(int)
void remove(Component)
void removeAll()
Remove one of or all of the components from this container. When present, the int argument indicates the position within the container of the component to remove
JRootPane getRootPane()Get the root pane that contains the component.
Container getTopLevelAncestor()Get the topmost container for the component — a Window, Applet, or null if the component has not been added to any container.
Container getParent()Get the component's immediate container.
int getComponentCount() Get the number of components in this container.

Component getComponent(int)
Component[] getComponents()
Get the one of or all of the components in this container. The int argument indicates the position of the component to get.
Component getComponentZOrder(int)
Component[] getComponentZOrder()
Returns the z-order index of the component inside the container. The higher a component is in the z-order hierarchy, the lower its index. The component with the lowest z-order index is painted last, above all other child components.
  • Laying Out Components
Method
Purpose
void setPreferredSize(Dimension)
void setMaximumSize(Dimension)
void setMinimumSize(Dimension)
Set the component's preferred, maximum, or minimum size, measured in pixels. The preferred size indicates the best size for the component. The component should be no larger than its maximum size and no smaller than its minimum size. Be aware that these are hints only and might be ignored by certain layout managers.
Dimension getPreferredSize()
Dimension getMaximumSize()
Dimension getMinimumSize()
Get the preferred, maximum, or minimum size of the component, measured in pixels. Many JComponent classes have setter and getter methods. For those non-JComponent subclasses, which do not have the corresponding setter methods, you can set a component's preferred, maximum, or minimum size by creating a subclass and overriding these methods.
void setAlignmentX(float)
void setAlignmentY(float)
Set the alignment along the x- or y- axis. These values indicate how the component would like to be aligned relative to other components. The value should be a number between 0 and 1 where 0 represents alignment along the origin, 1 is aligned the furthest away from the origin, and 0.5 is centered, and so on. Be aware that these are hints only and might be ignored by certain layout managers.
float getAlignmentX()
float getAlignmentY()
Get the alignment of the component along the x- or y- axis. For non-JComponent subclasses, which do not have the corresponding setter methods, you can set a component's alignment by creating a subclass and overriding these methods.
void setLayout(LayoutManager)
LayoutManager getLayout()
Set or get the component's layout manager. The layout manager is responsible for sizing and positioning the components within a container.
void applyComponentOrientation(ComponentOrientation) void setComponentOrientation(ComponentOrientation)Set the ComponentOrientation property of this container and all the components contained within it.
  • Getting Size and Position Information
Method
Purpose
int getWidth()
int getHeight()
Get the current width or height of the component measured in pixels.
Dimension getSize()
Dimension getSize(Dimension)
Get the component's current size measured in pixels. When using the one-argument version of this method, the caller is responsible for creating the Dimension instance in which the result is returned.
int getX()
int getY()
Get the current x or y coordinate of the component's origin relative to the parent's upper left corner measured in pixels.
Rectangle getBounds()
Rectangle getBounds(Rectangle)
Get the bounds of the component measured in pixels. The bounds specify the component's width, height, and origin relative to its parent. When using the one-argument version of this method, the caller is responsible for creating the Rectangle instance in which the result is returned.
Point getLocation()
Point getLocation(Point)
Gets the current location of the component relative to the parent's upper left corner measured in pixels. When using the one-argument version of getLocation method, the caller is responsible for creating the Point instance in which the result is returned.
Point getLocationOnScreen() Returns the position relative to the upper left corner of the screen.
Insets getInsets()Get the size of the component's border.
  • Specifying Absolute Size and Position
Method
Purpose
void setLocation(int, int)
void setLocation(Point)
Set the location of the component, in pixels, relative to the parent's upper left corner. The two int arguments specify x and y, in that order. Use these methods to position a component when you are not using a layout manager.
void setSize(int, int)
void setSize(Dimension)
Set the size of the component measured in pixels. The two int arguments specify width and height, in that order. Use these methods to size a component when you are not using a layout manager.
void setBounds(int, int, int, int)
void setBounds(Rectangle)
Set the size and location relative to the parent's upper left corner, in pixels, of the component. The four int arguments specify x, y, width, and height, in that order. Use these methods to position and size a component when you are not using a layout manager.

➤ Using Text Components

This section provides background information you might need when using Swing text components. If you intend to use an unstyled text component — a text field, password field, formatted text field, or text area — go to its how-to page and return here only if necessary. If you intend to use a styled text component, see How to Use Editor Panes and Text Panes, and read this section as well. If you do not know which component you need, read on.

Swing text components display text and optionally allow the user to edit the text. Programs need text components for tasks ranging from the straightforward (enter a word and press Enter) to the complex (display and edit styled text with embedded images in an Asian language).

Swing provides six text components, along with supporting classes and interfaces that meet even the most complex text requirements. In spite of their different uses and capabilities, all Swing text components inherit from the same superclass, JTextComponent, which provides a highly-configurable and powerful foundation for text manipulation.


The following figure shows the JTextComponent hierarchy.


The following picture shows an application called TextSamplerDemo that uses each Swing text component.


Try this: 
  1. Click the Launch button to run TextSamplerDemo using Java™ Web Start (download JDK 7 or later). Alternatively, to compile and run the example yourself, consult the example index.Launches the TextSamplerDemo Application
  2. Type some text in the text field and press Enter. Do the same in the password field. The label beneath the fields is updated when you press Enter.
  3. Try entering valid and invalid dates into the formatted text field. Note that when you press Enter the label beneath the fields is updated only if the date is valid.
  4. Select and edit text in the text area and the text pane. Use keyboard bindings, Ctrl-X, Ctrl-C, and Ctrl-V, to cut, copy, and paste text, respectively.
  5. Try to edit the text in the editor pane, which has been made uneditable with a call to setEditable.
  6. Look in the text pane to find an example of an embedded component and an embedded icon.

The TextSamplerDemo example uses the text components in very basic ways. The following table tells you more about what you can do with each kind of text component.

Group
Description
Swing Classes
Text Controls Also known simply as text fields, text controls can display only one line of editable text. Like buttons, they generate action events. Use them to get a small amount of textual information from the user and perform an action after the text entry is complete. JTextField and its subclasses JPasswordField and JFormattedTextField
Plain Text Areas JTextArea can display multiple lines of editable text. Although a text area can display text in any font, all of the text is in the same font. Use a text area to allow the user to enter unformatted text of any length or to display unformatted help information. JTextArea
Styled Text Areas A styled text component can display editable text using more than one font. Some styled text components allow embedded images and even embedded components. Styled text components are powerful and multi-faceted components suitable for high-end needs, and offer more avenues for customization than the other text components.
Because they are so powerful and flexible, styled text components typically require more initial programming to set up and use. One exception is that editor panes can be easily loaded with formatted text from a URL, which makes them useful for displaying uneditable help information.
JEditorPane
and its subclass
JTextPane

This Tutorial provides information about the foundation laid by the JTextComponent class and tells you how to accomplish some common text-related tasks.
  • Text Component Features
  • The Text Component API

➤ How to Use Various Components
How to Make Applets
How to Use Buttons, Check Boxes, and Radio Buttons
How to Use the ButtonGroup Component
How to Use Color Choosers
How to Use Combo Boxes
How to Make Dialogs
How to Use Editor Panes and Text Panes
How to Use File Choosers
How to Use Formatted Text Fields
How to Make Frames (Main Windows)
How to Use Internal Frames
How to Use Labels
How to Use Layered Panes
How to Use Lists
How to Use Menus
How to Use Panels
How to Use Password Fields
How to Use Progress Bars
How to Use Root Panes
How to Use Scroll Panes
How to Use Separators
How to Use Sliders
How to Use Spinners
How to Use Split Panes
How to Use Tabbed Panes
How to Use Tables
How to Use Text Areas
How to Use Text Fields
How to Use Tool Bars
How to Use Tool Tips
How to Use Trees
➤ How to Use HTML in Swing Components
➤ How to Use Models
➤ How to Use Icons
➤ How to Use Borders
➤ Solving Common Component Problems

«« Previous
Next »»