Read an Excerpt
Chapter 9: Internal FramesIn this Chapter:
Managing a DesktopCertain GUI applications need to simulate a desktop environment by allowing multiple "frames" to be displayed within a single root window. These frames typically look like the normal frames you'd see on a real desktop, but are not actually known to the window manager, because they are not really windows in the normal sense of the term. For some types of applications (word processors, IDEs, etc.), this can be a very powerful approach to UI design.
In this chapter, we'll look at a collection of classes Swing provides to allow you to create this type of application in Java. At the end of the chapter, we'll provide a large sample program that shows how to implement a variety of useful features.
OverviewBefore looking at each of the classes involved in the Swing desktop/internal frame model, we'll take a moment for an overview of how they all work together. Figure 9-1 shows the relationships between the classes we'll be covering in this chapter.
A JInternalFrame is a container that looks much like a JFrame. The key difference is that internal frames can only exist within some other Java container. JInternalFrame implements the following six interfaces: Accessible, MouseListener, MouseMotionListener, WindowConstants, RootPaneContainer, ComponentListener.
Each internal frame keeps a reference to an instance of the static inner class called JDesktopIcon. Like real frames, JInternalFrames can be iconified. JDesktop Icon is the class responsible for taking the place of the frame when it gets iconified.
Though it is not required, JInternalFrames are typically used inside of a JDesktopPane. JDesktopPane is an extension of JLayeredPane that adds direct support for managing a collection of JInternalFrames in layers. JDesktopPane uses an object called a DesktopManager to control how different behavior, like iconification or maximization, is carried out. A default implementation of this interface, DefaultDesktopManager, is provided. We'll see how all of this functionality is broken out as we cover the various classes and interfaces involved.
One more thing to notice about Figure 9-1 is that JInternalFrame supports a new type of listener called InternalFrameListener. This interface contains methods that match those defined by the AWT WindowListener class, but have slightly different names and take InternalFrameEvents, rather than WindowEvents, as input.
The JInternalFrame ClassJInternalFrame is a powerful addition to Java, providing the ability to create lightweight frames that exist inside other components. An internal frame is managed entirely within some other Java container, just like any other component, allowing the program complete control over iconification, maximization, resizing, etc. Despite looking like "real" windows, the underlying windowing system knows nothing of the existence of internal frames.* Figure 9-2 shows what an internal frame looks like in the different look-and-feels.
There's quite a lot to discuss about JInternalFrames, but most of their power comes when they are used inside a JDesktopPane. In this section, we will give a quick overview of the properties, constructors, and methods available in JInternalFrame, but we'll leave the more detailed discussion of using internal frames to the sections that follow.
PropertiesJInternalFrame defines the properties and default values shown in Table 9-1.
The accessibleContext property is as expected. The background and foreground properties are delegated to the frame's content pane.
There are three pairs of properties that indicate whether or not something can be done to a frame and whether or not that thing is currently done to the frame.
Table 9-1. JInternalFrame Properties
They are: closable/closed, iconifiable/icon, and maximizable/maximum. Note that closed, icon, and maximum are constrained properties.
The contentPane, glassPane, layeredPane, and menuBar properties come from the RootPaneContainer interface and are taken directly from the frame's JRootPane. The rootPane property is set to a new JRootPane when the frame is constructed.
The value of the defaultCloseOperation property defaults to Windowconstants.HIDE_ON_CLOSE. This implies that when the frame is closed, its setClosed ( ) method will be called. The frame could be reopened at a later time.
The desktopIcon reflects how the frame will be displayed when iconified. A JDesktopIcon (which leaves the rendering to the L&F) is created for the frame when it is instantiated. The desktopPane property provides a convenient way to access the JDesktopPane containing the frame, if there is one.
FrameIcon is the icon painted inside the frame's titlebar (usually on the far left). By default, there is no icon. However, the basic look-and-feel checks to see if a frameIcon has been set and, if not, paints the 'Java cup" icon. This explains why an icon appears in the Windows L&F frame shown in Figure 9-2, but not in the others (which provide their own paint ( ) implementations, rather than using the one provided by the basic L&F).*
The layer property indicates the frame's current layer, if it has been placed in a JLayeredPane. The resizable property indicates whether or not the frame can be resized by dragging its edges or corners, and selected indicates whether or not the frame has been selected (this will typically determine the color of the titlebar). Note that selected is a constrained property. Title contains the string to appear on the titlebar.
The Ul property holds the current L&F implementation for the frame, and UIClassID reflects the class ID for internal frames.
Finally, the warningString property, which is always null, is used to specify the string that should appear in contexts where the frame might be insecure. This is the technique used by java.awt. Window to display a string like "Warning: Applet Window" when a Java window is displayed from an applet. Since JInternalFrames are always fully enclosed by some other top-level container, this property is always null. . . .