Graphic Java 2: Mastering the Jfc, By Geary, 3Rd Edition, Volume 2: Swing

Before we start coding, here's a brief rundown of the features of an internal frame:

  • Same functions as a normal Frame object, but confined to the visible area of the container it is placed in

  • Can be iconified (icon stays inside main application frame)

  • Can be maximized (frame consumes entire main application frame area)

  • Can be closed using the standard controls for application windows

  • Can be placed in a "layer," which dictates how the frame displays itself relative to other internal frames (a frame in layer 1 can never hide a frame in layer 2)

To be honest, in practice, standalone frames are often more useful than internal frames. You'll want to know about both; we have chapters dedicated to each of these topics (Chapter 8 and Chapter 9, respectively).

Figure 2-6 shows a simple internal frame using the Metal L&F.

Figure 2-6. The SimpleInternalFrame application using the Metal L&F

For this first example, we'll add an empty internal frame to an application. Once that's working, we'll expand the simple frame to create a couple of different types of internal frames and create the framework for a simple application.

One of the prerequisites for using internal frames is that you need a window capable of managing them. The Swing package provides the JDesktopPane class for this purpose. You'll see the details of the JDesktopPane in Chapter 9, but for now, here's how to get one started:

// Set up the layered pane. JDesktopPane desktop = new JDesktopPane( ); add(desktop, BorderLayout.CENTER);

With the desktop in place, you can create a new internal frame and show it. The JInternalFrame constructor takes five arguments that tailor the look and functionality of the frame:

public JInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable);

We'll turn on every feature for the example. The following makes the internal frame visible:

internalFrame = new JInternalFrame("Internal Frame", true, true, true, true); internalFrame.setBounds(50, 50, 200, 100); desktop.add(internalFrame, new Integer(1));

The desktop.add( ) call does the real work here. You supply the internal frame and the "layer" your frame belongs in. Layers are Integer objects. The values determine the order of your layers and what shows on top of what. For example, frames in layer 2 always show on top of frames in layer 1, even if the frame in layer 1 has the keyboard focus. But you do need to remember to give your frame both a size and a location. The internal frames have default preferred and minimum sizes of 0 x 0.

Figure 2-7 shows how the JInternalFrame class also takes advantage of Swing's pluggable L&F feature. You can switch the appearance of the frames, just like you did with the buttons.

Figure 2-7. The SimpleInternalFrame in the Motif (left) and Windows (right) L&Fs

You can even iconify these frames. They turn into an "iconified box" appropriate for the current L&F. Figure 2-8 shows an iconified frame.

Figure 2-8. An iconified internal frame in the Mac (left) and Metal (right) L&Fs

Here's the complete application with an open button and an internal frame. When you click the button, it pops up the internal frame. You can use the button in the upper-right corner of the frame to close it (providing you're using either the Metal or the Windows L&F). You can use the other buttons in the main frame to adjust the L&F of the internal frame:

// SimpleInternalFrame.java // A quick demonstration of setting up an internal frame in an application // import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SimpleInternalFrame extends Frame { JButton openButton, macButton, javaButton, motifButton, winButton; JLayeredPane desktop; JInternalFrame internalFrame; public SimpleInternalFrame( ) { super("Internal Frame Demo"); setSize(500,400); openButton = new JButton("Open"); macButton = new JButton("Mac"); javaButton = new JButton("Metal"); motifButton = new JButton("Motif"); winButton = new JButton("Windows"); Panel p = new Panel( ); p.add(openButton); p.add(macButton); p.add(javaButton); p.add(motifButton); p.add(winButton); add(p, BorderLayout.SOUTH); addWindowListener(new WindowAdapter( ) { public void windowClosing(WindowEvent e) { System.exit(0); } }); openButton.addActionListener(new OpenListener( )); LnFListener lnf = new LnFListener(this); macButton.addActionListener(lnf); javaButton.addActionListener(lnf); motifButton.addActionListener(lnf); winButton.addActionListener(lnf); // Set up the layered pane. desktop = new JDesktopPane( ); desktop.setOpaque(true); add(desktop, BorderLayout.CENTER); } // An inner class to handle presses of the Open button class OpenListener implements ActionListener { public void actionPerformed(ActionEvent e) { if ((internalFrame == null) || (internalFrame.isClosed( ))) { internalFrame = new JInternalFrame("Internal Frame", true, true, true, true); internalFrame.setBounds(50, 50, 200, 100); desktop.add(internalFrame, new Integer(1)); internalFrame.setVisible(true); } } } public static void main(String args[]) { SimpleInternalFrame sif = new SimpleInternalFrame( ); sif.setVisible(true); } }

The internal frame examples use the same L&F listener and basic window monitor as the JButton example. You'll notice some nasty flickering when you move the internal frame around. That's because we put it inside a Frame, not a JFrame. In our next example, the problem disappears.

Категории