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

How to Use Root Panes

In general, you don't directly create a JRootPane(in the API reference documentation) object. Instead, you get a JRootPane (whether you want it or not!) when you instantiate JInternalFrame or one of the top-level Swing containers -- JApplet, JDialog, JFrame, and JWindow.

The section General Rules for Using Swing Components tells you the basics of using root panes -- getting the content pane, setting its layout manager, and adding Swing components to it. This section tells you more about root panes, including the components that make up a root pane and how you can use them. Another place to get information about root panes is The Swing Connection, especially the article Understanding Containers.

[PENDING: Insert figure that shows front and side views of a JRootPane in a JFrame.]

As the preceding figure shows, a root pane has four parts:

The glass pane
Hidden, by default. If you make the glass pane visible, then it's like a sheet of glass over all the other parts of the root pane. It's completely transparent (unless you implement the glass pane's paint method so that it does something) and it intercepts input events for the root pane. In the next section, you'll see an example of using a glass pane.
The layered pane
Serves to position its contents, which consist of the content pane and the optional menu bar. Can also hold other components in a specified Z order. For information, see How to Use Layered Panes.
The content pane
The container of the root pane's visible components, excluding the menu bar. For information on using the content pane, see Setting Up Windows and Building a Swing GUI. [PENDING: consolidate, clarify content pane coverage.]
The optional menu bar
The home for the root pane's container's menus. If the container has a menu bar, you generally use the container's setMenuBar or setJMenuBar method to put the menu bar in the appropriate place. [PENDING: CHECK] For more information on using menus and menu bars, see [PENDING: soon-to-be-written menu page].

The Glass Pane

The glass pane is useful when you want to be able to catch events or draw over an area that already contains one or more components. For example, you can deactivate mouse events for a multi-component region by having the glass pane intercept the events. Or you can display a wait cursor over an entire root pane using the glass pane.

Here's a picture of an application that demonstrates glass pane features. It contains a radio button that lets you set whether the glass pane is "visible" -- whether it can get events and paint itself onscreen. When the glass pane is visible, it blocks all input events from reaching the components in the content pane. It also draws a red dot in the place where it last detected a mouse-pressed event.


Try this:
  1. Compile and run the application. The source file is GlassPaneDemo.java.
    See Getting Started with Swing if you need help.
  2. Click Button 1.
    The button's appearance changes to show that it's been clicked.
  3. Click the radio button so that the glass pane becomes "visible," and then click Button 1 again.
    The button does not detect the mouse-pressed event because the glass pane intercepts it. When the glass pane detects the event, it beeps and draws a red circle where you clicked.
  4. Click the radio button again so that the glass pane is hidden.
    When the root pane detects an event over the radio button, it forwards it to the radio button. Otherwise, the radio button would not respond to clicks.

Below is the code from GlassPaneDemo.java that shows and hides the glass pane. This program happens to create its own glass pane, setting it using the JFrame setGlassPane method. However, if a glass pane doesn't do any drawing, the program might simply attach listeners to the default glass pane, as returned by getGlassPane.

...//where GlassPaneDemo's UI is initialized:
JRadioButton changeButton = new JRadioButton(...);
changeButton.addItemListener(new ItemListener() {
    public void itemStateChanged(ItemEvent e) {
        myGlassPane.setVisible(e.getStateChange() 
                             == ItemEvent.SELECTED);
    }
});

Here is the code that implements the mouse-event handling for the glass pane. The liveOne instance variable refers to the radio button that determines the visibility of the glass pane. If a mouse event occurs over the radio button, then the glass pane redispatches the event so that the radio button receives it. So that the button behaves properly, it also receives all drag events that started with a button press.

...//In the implementation of the glass pane's mouse listener:
public void mouseMoved(MouseEvent e) {
    redispatchMouseEvent(e, false);
}
...
public void mouseDragged(MouseEvent e) {
    redispatchMouseEvent(e, false);
}
...
public void mouseReleased(MouseEvent e) {
    redispatchMouseEvent(e, true);
    isButtonDrag = false;
}

private void redispatchMouseEvent(MouseEvent e,
                                  boolean repaint) {
    Point panePoint = e.getPoint();
    Point buttonPoint = SwingUtilities.convertPoint(
                                    glassPane,
                                    panePoint, 
                                    liveOne);
    boolean inButton = liveOne.contains(buttonPoint);
    int eventID = e.getID();

    if (inButton && (eventID == MouseEvent.MOUSE_PRESSED)) {
        inButtonDrag = true;
    } 

    if (inButton || inButtonDrag) {
        liveOne.dispatchEvent(new MouseEvent(liveOne,
                                             eventID,
                                             e.getWhen(),
                                             e.getModifiers(),
                                             buttonPoint.x,
                                             buttonPoint.y,
                                             e.getClickCount(),
                                             e.isPopupTrigger()));
    }

    if (repaint) {
        toolkit.beep();
        glassPane.setPoint(panePoint);
        glassPane.repaint();
    }
}
Here is the code that implements the drawing for the glass pane:
...//where GlassPaneDemo's UI is initialized:
myGlassPane = new MyGlassPane(...);
frame.setGlassPane(myGlassPane);
...
/**
 * We have to provide our own glass pane so that it can paint.
 */
class MyGlassPane extends JComponent {
    Point point = null;

    public void paint(Graphics g) {
    	if (point != null) {
	    g.setColor(Color.red);
    	    g.fillOval(point.x - 10, point.y - 10, 20, 20);
    	}
    }
    ...
}
[PENDING: Put API summary here.]


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