I l@ve RuBoard |
![]() ![]() |
8.4 The JFrame ClassThe most common Swing container for Java applications is the JFrame class. Like java.awt.Frame, JFrame provides a top-level window with a title, border, and other platform-specific adornments (e.g., minimize, maximize, and close buttons). Because it uses a JRootPane as its only child, working with a JFrame is slightly different than working with an AWT Frame. An empty JFrame is shown in Figure 8-9. Figure 8-9. Empty JFrame instances on Unix, Mac, and Windows platforms![]() The primary difference is that calls to add( ) must be replaced with calls to getContentPane( ).add( ). In fact, the addImpl( ) method is implemented so that a call made directly to add( ) throws an Error. (The error message tells you not to call add( ) directly.) 8.4.1 PropertiesJFrame defines the properties shown in Table 8-8. The accessibleContext property is as expected. ContentPane , glassPane, layeredPane, and JMenuBar are really properties of JRootPane (described earlier in the chapter). JFrame provides direct access to these panes, as required by the RootPaneContainer interface.
The defaultCloseOperation is set to HIDE_ON_CLOSE, a value taken from WindowConstants. This indicates that closing a JFrame window results in a call to setVisible(false). The layout property is listed here because JFrame overrides setLayout( ) to throw an Error if an attempt is made to change the layout manager, rather than set the layout manager of the frame's content pane. The rootPane property is set to a new instance of JRootPane when the frame is created and cannot be changed (via public methods). The rootPaneCheckingEnabled property determines whether you get those error messages when trying to add components directly to the root pane. The accessors for the title property are inherited from Frame. This property can also be set in the JFrame constructor. 8.4.2 ConstructorsAll constructors can now (since 1.4) potentially throw HeadlessException if the graphics environment is operating in a "headless" mode, meaning that there is no display, keyboard, or mouse. This would be true, for example, in a servlet environment that used Swing to generate graphics to be sent to a web browser as downloaded image files. The versions that specify a GraphicsConfiguration (introduced in 1.3 for JFrame) allow you to select the display device on which the dialog should appear if your application is running in a multi-screen environment.
8.4.3 Protected MethodsJFrame has a few protected methods that you should know about. If you extend JFrame, you can override them to alter the default behavior. In particular, if you don't want the frame responding to windowClosing( ) events at all, you can provide an empty implementation of the processWindowEvent( ) method. This will leave you with the responsibility of closing the frame programmatically. The next section has an example of extending processWindowEvent( ) to confirm that the user really wants to close the frame.
8.4.4 Exiting FramesIn many applications, closing the main application frame should cause the program to exit (shutting down the virtual machine). The default implementation, however, is only to hide the frame when it is closed, leaving the virtual machine running with no visible frame. We'll briefly look at two simple ways to get the program to exit when the frame is closed. The simplest thing to do is to set the close operation to exit: // FrameClose1.java // import javax.swing.JFrame; public class FrameClose1 { public static void main(String[] args) { JFrame mainFrame = new JFrame( ); // Exit app when frame is closed. mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainFrame.setSize(320, 240); mainFrame.setVisible(true); } } Another alternative that works with SDKs prior to 1.3 is to add a WindowListener to the frame, calling System.exit( ) in the windowClosing( ) method. Here's a simple example: // FrameClose2.java // import javax.swing.JFrame; import java.awt.event.*; public class FrameClose2 { public static void main(String[] args) { JFrame mainFrame = new JFrame( ); // Exit app when frame is closed. mainFrame.addWindowListener(new WindowAdapter( ) { public void windowClosing(WindowEvent ev) { System.exit(0); } }); mainFrame.setSize(320, 240); mainFrame.setVisible(true); } } If you get tired of writing this same block of code in every frame that needs to close properly, you might want to use an extension of JFrame that supports this feature. Here's one possible implementation of such a class: // ExitFrame.java // import javax.swing.JFrame; import java.awt.event.WindowEvent; // A very simple extension of JFrame that defaults to EXIT_ON_CLOSE for // its close operation. Relies on the 1.3 or higher SDK. public class ExitFrame extends JFrame { public ExitFrame( ) { super( ); setDefaultCloseOperation(EXIT_ON_CLOSE); } public ExitFrame(String title) { super(title); setDefaultCloseOperation(EXIT_ON_CLOSE); } } You can use this class just like you'd use a JFrame. If you don't want the program to exit when the user closes the frame, just change the default close action to one of the values defined in WindowConstants. A more common strategy is to display a dialog box asking something like, "Are you sure?" when the user tries to close the frame. JOptionPane (which we'll discuss in detail in Chapter 10) makes this very easy to do. All you need to do is reimplement your processWindowEvent( ) method like this: protected void processWindowEvent(WindowEvent e) { if (e.getID( ) == WindowEvent.WINDOW_CLOSING) { int exit = JOptionPane.showConfirmDialog(this, "Are you sure?"); if (exit == JOptionPane.YES_OPTION) { System.exit(0); } } // If you don't want listeners processing the WINDOW_CLOSING events, you could put // this next call in an else block for the if (e.getID( )...) statement. That way, // only the other types of Window events (iconification, activation, etc.) would be // sent out. super.processWindowEvent(e); } ![]() |
I l@ve RuBoard |
![]() ![]() |