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

How to Use Internal Frames (MDI-Style Windows)

With the JInternalFrame(in the API reference documentation) class, you can display a JFrame-like window within another window. Usually, you display internal frames within a JDesktopPane(in the API reference documentation). JDesktopPane is a subclass of JLayeredPane that has added API for managing multiple overlapping internal frames. Generally, you put the desktop pane into the content pane of a JFrame.

Here's a picture of an application that has two internal frames inside a regular frame.

As the figure shows, the internal frames use the window decorations for the Metal look and feel. However, the window that contains them has the decorations for the native look and feel (in this case, Motif).

Try this:
  1. Compile and run the application. The source files are InternalFrameDemo.java and MyInternalFrame.java.
    See Getting Started with Swing if you need help.
  2. Create new internal frames using the Create item in the Document menu.
    Each internal frame comes up 30 pixels lower and to the right of the place where the previous internal frame first appeared. This functionality is implemented in the MyInternalFrame class, which is the custom subclass of JInternalFrame.

The following code, taken from InternalFrameDemo.java, creates the desktop and internal frames in the previous example.

...//In the constructor of InternalFrameDemo, a JFrame subclass:
    desktop = new JDesktopPane(); //a specialized layered pane
    createFrame(); //Create first window
    setContentPane(desktop);
...
protected void createFrame() {
    MyInternalFrame frame = new MyInternalFrame();
    desktop.add(frame);
    try {
        frame.setSelected(true);
    } catch (java.beans.PropertyVetoException e2) {}
}

...//In the constructor of MyInternalFrame, a JInternalFrame subclass:
static int openFrameCount = 0;
static final int xOffset = 30, yOffset = 30;

public MyInternalFrame() {
    super("Internal Frame #" + (++openFrameCount), 
          true, //resizable
          true, //closable
          true, //maximizable
          true);//iconifiable
    //...Create the GUI and put it in the window...
    //...Then set the window size or call pack...
    ...
    //Set the window's location.
    setLocation(xOffset*openFrameCount, yOffset*openFrameCount);
}

How Internal Frames Differ from Regular Frames

Because internal frames have root panes, setting up the GUI for a JInternalFrame is very similar to setting up the GUI for a JFrame. However, because internal frames are lightweight components and aren't true windows, they differ from regular frames in the following ways:
You must add an internal frame to a container.
If you forget to add the internal frame to a container (usually a JDesktopPane), the internal frame won't appear.
Internal frames fire internal frame events, not window events.
Handling internal frame events is almost identical to handling window events. See How to Write an Internal Frame Listener for more information.
Dialogs for internal frames should be implemented using JInternalFrame, not JDialog.
To create a modal dialog, you can use the JOptionPane showInternalXxx methods instead of the showXxx methods described in How to Make Dialogs.
[PENDING: WHAT ELSE?]

Note: Due to a bug in Swing 1.0.2 (#4128975), once an internal frame has appeared and then been hidden, the internal frame can't appear again. If you want to show a window again, you must recreate it, as InternalFrameEventDemo.java does.

The Internal Frame API

The following tables list the commonly used JInternalFrame constructors and methods. The API for using internal frames falls into these categories:

Besides the API listed below, JInternalFrames can and do use API defined in JComponent, Container, and Component. Some commonly used methods are those that set the size and location of the internal frame: pack, setSize, setLocation, and setBounds.

Creating the Internal Frame
Constructor Purpose
JInternalFrame()
JInternalFrame(String)
JInternalFrame(String, boolean)
JInternalFrame(String, boolean, boolean)
JInternalFrame(String, boolean, boolean, boolean)
JInternalFrame(String, boolean, boolean, boolean, boolean)
Create a JInternalFrame instance. The first argument specifies the title (if any) to be displayed by the internal frame. The rest of the arguments specify whether the internal frame should contain decorations allowing the user to resize, close, maximize, and iconify the internal frame (specified in that order). The default value for each boolean argument is false, which means that the operation is not allowed.

Taking Advantage of Unique Internal Frame Capabilities
Method Purpose
void addInternalFrameListener(InternalFrameListener)
void removeInternalFrameListener(InternalFrameListener)
Add or remove an internal frame listener. See How to Write an Internal Frame Listener for more information. [PENDING: this method probably belongs in another category]
void setFrameIcon(Icon)
Icon getFrameIcon()
Set or get the icon displayed in the title bar of the internal frame (usually in the top-left corner).
void setClosable(boolean)
boolean isClosable()
Set or get whether the user can close the internal frame.
void setClosed(boolean)
boolean isClosed()
Set or get whether the internal frame is currently closed.
void setIcon(boolean)
boolean isIcon()
Iconify or deiconify the internal frame, or determine whether it's currently iconified.
void setIconifiable(boolean)
boolean isIconifiable()
Set or get whether the internal frame can be iconified.
void setMaximizable(boolean)
boolean isMaximizable()
Set or get whether the user can maximize this internal frame.
void setMaximum(boolean)
boolean isMaximum()
Maximize or restore the internal frame, or determine whether it's maximized.
void setResizable(boolean)
boolean isResizable()
Set or get whether the internal frame can be resized.
void setSelected(boolean)
boolean isSelected()
Set or get whether the internal frame is the currently "selected" (activated) internal frame.

Setting and Getting the Internal Frame's Helper Objects
Method Purpose
void setContentPane(Container)
Container getContentPane()
Set or get the internal frame's content pane. You can also set or get this through the internal frame's root pane.
JRootPane createRootPane()
void setRootPane(JRootPane)
JRootPane getRootPane()
Create, set, or get the internal frame's root pane. The root pane manages the interior of the internal frame including the content pane, the glass pane, and so on.
void setMenuBar(JMenuBar)
JMenuBar getMenuBar()
Set or get the internal frame's menu bar. You can also set or get this through the internal frame's root pane. Note that these method names contain no "J", unlike the equivalent JFrame methods.
void setGlassPane(Component)
Component getGlassPane()
Set or get the internal frame's glass pane. You can also set or get this through the internal frame's root pane.
void setLayeredPane(JLayeredPane)
JLayeredPane getLayeredPane()
Set or get the internal frame's layered pane. You can also set or get this through the internal frame's root pane.

Using a Desktop Pane
Constructor or Method Purpose
JDesktopPane() Creates a new instance of JDesktopPane.
JInternalFrame[] getAllFrames() Returns all JInternalFrame objects that the desktop contains.
JInternalFrame[] getAllFramesInLayer(int) Returns all JInternalFrame objects that the desktop contains that are in the specified layer. See How to Use Layered Panes for information about layers.

Examples that Use Internal Frames

The following examples use internal frames. Because internal frames are similar to regular frames, you should also look at Examples that Use JFrame.

Example Where Described Notes
MyInternalFrame.java This page. Implements an internal frame that appears at an offset to the previously created internal frame.
InternalFrameDemo.java This page. Lets you create internal frames (instances of MyInternalFrame) that go into the application's JDesktopPane.
InternalFrameEventDemo.java How to Write an Internal Frame Listener Demonstrates listening for internal frame events. Also demonstrates positioning internal frames within a desktop pane.
LayeredPaneDemo.java How to Use Layered Panes Demonstrates putting internal frames into various layers of a layered pane.


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