Previous | Next | Trail Map | Creating a GUI with JFC/Swing | Using Swing Components

How to Use Layered Panes

A layered pane is a Swing container that provides a third dimension for positioning components: depth, also known as Z order. When adding a component to a layered pane, you specify its depth. Components at a higher depth overlap components at a lower depth and components at a lower depth are under components at a higher depth. The relationship between components at the same depth is determined by their positions within the depth. For convenience, layered pane defines several layers within the possible range of depths for specific functions. For example, you can put a component on the highest layer, the drag layer, when dragging components.

Swing provides two layered pane classes. The first, JLayeredPane(in the API reference documentation), is the class that root panes use. The second, JDesktopPane, is a JLayeredPane subclass that's specialized for the task of holding internal frames. The example in this section uses an instance of JLayeredPane. For examples of using JDesktopPane, see How to Use Internal Frames.


Note: [PENDING: mention that layered panes don't work with internal frames in some releases of Swing?]

Every Swing container that has a root pane -- such as JFrame, JApplet, JDialog, and JInternalFrame -- automatically has a layered pane, although many programs don't explicitly use the layered pane. [PENDING: link to high-level discussion of this] You can also create your own layered pane and use it anywhere you can use a regular Swing container.

Here's a picture of a demo application that uses a layered pane to place colored labels on different layers:


Try this:
  1. Compile and run the application. The source file is LayeredPaneDemo.java. You will also need the dukeWaveRed.gif image file.
    See Getting Started with Swing if you need help.
  2. Move the mouse around in the lower part of the window. The image of Duke drags behind the Drag Layer and Popup layer labels and in front of the labels on the other three layers.
  3. Use the combo box at the top of the window to change Duke's layer. Use the check box to set whether Duke is in position 0 within the current layer.

Here's the code that creates and sets up the layered pane:
//Create the dragging area at the bottom of the window
Dimension layeredPaneSize = new Dimension(300, 310);
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(layeredPaneSize);
layeredPane.setBorder(BorderFactory.createTitledBorder(
				 "Move the Mouse to Move Duke"));
layeredPane.addMouseMotionListener(new MouseMotionAdapter() {
    public void mouseEntered(MouseEvent e) {
	dragLabel.setBounds(e.getX()-15, e.getY()-10,
			    iconWidth, iconHeight);
    }
    public void mouseMoved(MouseEvent e) {
	dragLabel.setBounds(e.getX()-15, e.getY()-10,
			    iconWidth, iconHeight);
    }
});    
This code creates a layered pane, gives it a preferred size and a border, and adds a mouse motion listener to it. Now let's look at the code that adds the colored labels to the layered pane at different depths.
//This is the origin of the default layer's label
//and the size of all the layers' labels.
Point origin = new Point(10, 20);
Dimension size = new Dimension(140, 140);

//For each layer, add a colored label overlapping the last
for (int i = 0 ; i < layerValues.length; i++) {

    //Create and set up colored label
    JLabel label = new JLabel(/*text for label*/);
    ...

    //Position and size it the hard way
    label.setBounds(origin.x, origin.y, size.width, size.height);

    //Add it to the layered pane
    layeredPane.add(label, /*depth*/);

    //Adjust origin for next layer
    origin.x += 35;
    origin.y += 35;
}
Two statements are shown in bold font. The first sets the bounds of the label, which includes the label's x and y position as well as its width and height. You have to set each components x and y position explicitly because by default layered panes don't have a layout manager. You can set a layered pane's layout manager, but the layout manager will arrange the components as if they were all on one layer. Most programs use an intermediate container to contain and position components on the same layer, but use absolute positioning(in the Creating a User Interface trail) to layout components on different layers.

The second bold statement adds the label to the layered pane and sets its depth. In this example, each colored label is added to a different layer. The add method used in this program takes two arguments: The first is the component to add; the second is an Integer indicating the depth at which to put the component. You can use any Integer to specify depth. However, this example and most other programs use one of those defined by the JLayeredPane class:

Layer NameValueDescription
FRAME_CONTENT_LAYER new Integer(-30000) This layer is used to position the frame's content pane and menu bar. Most programs won't use this.
DEFAULT_LAYER new Integer(0) Most components go in this layer.
PALETTE_LAYER new Integer(100) This layer is useful for floating toolbars and palettes.
MODAL_LAYER new Integer(200) Modal dialogs, such as those provided by JOptionPane, belong in this layer.
POPUP_LAYER new Integer(300) Popups go in this layer because they need to appear above just about everything.
DRAG_LAYER new Integer(400) Move a component to this layer when dragging. Return the component to its regular layer when dropped.
Here's the code that creates the label with Duke's image and adds it to the layered pane:

//Create and add the drag label (duke image) to the layered pane
dragLabel = new JLabel(icon);
dragLabel.setBounds(15, 225, iconWidth, iconHeight);
layeredPane.add(dragLabel, JLayeredPane.MODAL_LAYER, 0);
Note that this code uses a three argument version of the add method. The third argument specifies the Duke label's position within its layer which determines its relationship with other components at the same depth. Positions are specified with an int between -1 and (N-1), where N is the number of components at the depth. Unlike layer numbers, the lower the position number, the higher the component within its depth. Using -1 is the same as using N-1; it indicates the bottom-most position. Using 0 specifies that the component should be in the top-most position within its depth. As the following figure shows, with the exception of -1, a lower position number indicates a higher position within a depth.
Both a component's layer and its relative position within its layer can change. In the example, the combo box changes Duke's layer and the check box changes Duke's position within the layer. The check box and the combo box share the same action listener, which has this actionPerformed method:
public void actionPerformed(ActionEvent e) {

    //event came from the combo box...change Duke's layer
    if (e.getSource().equals(layerList))
        layeredPane.setLayer(dragLabel,
	          layerValues[layerList.getSelectedIndex()].intValue(),
	          onTop.isSelected()?0:1);

    //event came from the combo box...change Duke's layer
    else {
        if (onTop.isSelected())
	    layeredPane.moveToFront(dragLabel);
        else
	    layeredPane.moveToBack(dragLabel);
    }
}
When the user chooses a new layer with the combo box, the code changes Duke's layer by using the setLayer method. This version of setLayer requires a position as well. The code computes the position value based on the check box's selected state. JLayeredPane provides a two-argument version of setLayer that requires only the component and layer. Use that method if you want the components to be positioned based on the order in which they were added to the layered pane (last on top, first on bottom). When the user selects the check box, the moveToFront method moves Duke to the front (position 0). And when the user deselects check box, Duke gets moved to the back with the moveToBack method.


A Note of Caution: When adding a component to a layered pane you specify the layer with an Integer. When using setLayer to change a component's layer, you use an int. Use the API tables below to check the types of the arguments and return values for other methods in this class that deal with layers.

The Layered Pane API

The following tables list the commonly used JLayeredPane constructors and methods. Other methods you're likely to call are defined by the JComponent(in the API reference documentation) and Component(in the API reference documentation) classes and include [PENDING: anything in particular for JLayeredPane?]. [Link to JComponent and Component discussions.]

The API for using layered pane falls into these categories:

Creating or Getting a Layered Pane
Method Purpose
JLayeredPane() Create a layered pane.
JLayeredPane getLayeredPane()
(in JApplet, JDialog, JFrame, and JInternalFrame)
Get the layered pane in an applet, dialog, frame, or internal frame.

Layering Components
Method Purpose
void add(Component, Integer)
void add(Component, Integer, int)
Add the specified component to the layered pane. The second argument indicates the layer. The third argument, when present, indicates the component's position within its layer.
void setLayer(Component, int)
void setLayer(Component, int, int)
Change the component's layer. The second argument indicates the layer. The third argument, when present, indicates the component's position within its layer.
int getLayer(Component)
int getLayer(JComponent)
Get the layer for the specified component.
int getComponentCountInLayer(int) Get the number of components in the specified layer. The value returned by this method can be useful for computing position values.
Component[] getComponentsInLayer(int) Get an array of all the components in the specified layer.
int highestLayer()
int lowestLayer()
Compute the highest or lowest layer currently in use.

Setting Components' Intra-Layer Positions
Method Purpose
void setPosition(Component, int)
int getPosition(Component)
Set or get the position for the specified component within its layer.
void moveToFront(Component)
void moveToBack(Component)
Move the specified component to the front or back of its layer.

Examples that Use Layered Panes

This table shows the examples that use JLayeredPane and where those examples are described.

Example Where Described Notes
LayeredPaneDemo.java This page. Illustrates layers and intra-layer positions of a JLayeredPane.
InternalFrameDemo.java How to Use Internal Frames Uses a JDesktopFrame to manage internal frames.


Previous | Next | Trail Map | Creating a GUI with JFC/Swing | Using Swing Components