6.5 FramesThe Frame is a special type of Window that looks like other high level programs in your windowing environment. It adds a MenuBar, window title, and window gadgets (like resize, maximize, minimize, window menu) to the basic Window object. All the menu-related pieces are discussed in Chapter 10, Would You Like to Choose from the Menu? The default layout manager for a Frame is BorderLayout. Frame ConstantsThe Frame class includes a number of constants used to specify cursors. These constants are left over from Java 1.0 and maintained for compatibility. In Java 1.1, you should use the new Cursor class, introduced in the previous chapter, and the Component.setCursor() method to change the cursor over a frame. Avoid using the Frame constants for new code. To see these cursors, refer to Figure 5.6.
public final static int DEFAULT_CURSOR
HAND_CURSOR and MOVE_CURSOR are not available on Windows platforms with Java 1.0. If you ask to use these and they are not available, you get DEFAULT_CURSOR.
Frame Constructors
Frame Methods
java.awt.Frame[44,44,300x300,layout=java.awt.BorderLayout, resizable,title=] Frame EventsIn Java 1.0, a Frame peer generates all the events that are generated by the Component class; it does not generate events that are specific to a particular type of component. That is, it generates key events, mouse events, and focus events; it doesn't generate action events or list events. If an event happens within a child component of a Frame, the target of the event is the child component, not the Frame.Window In addition to the Component events, Frame generates the WINDOW events. These events are WINDOW_DESTROY, WINDOW_EXPOSE, WINDOW_ICONIFY, WINDOW_DEICONIFY, and WINDOW_MOVED. One common event, WINDOW_DESTROY, is generated when the user tries to close the Frame by selecting Quit, Close, or Exit (depending on your windowing environment) from the window manager's menu. By default, this event does nothing. You must provide an event handler that explicitly closes the Frame. If you do not, your Frame will close only when the Java Virtual Machine exits--for example, when you quit Netscape Navigator. The handleEvent() method in the following example, or one like it, should therefore be included in all classes that extend Frame. If a WINDOW_DESTROY event occurs, it gets rid of the Frame and exits the program. Make sure your method calls super.handleEvent() to process the other events.
public boolean handleEvent (Event e) { if (e.id == Event.WINDOW_DESTROY) { hide(); dispose(); System.exit(0); return true; // boolean method, must return something } else { // handle other events we find interesting } // make sure normal event processing happens return super.handleEvent (e); } With the 1.1 event model, you register listeners for different event types; the listeners are told when the event happens. The Frame class inherits all its listener handling from Window. Here's the Java 1.1 code necessary to handle WINDOW_CLOSING events; it is equivalent to the handleEvent() method in the previous example. First, you must add the following line to the Frame's constructor:
enableEvents (AWTEvent.WINDOW_EVENT_MASK); This line guarantees that we will receive window events, even if there is no listener. The processWindowEvent() method in the following code does the actual work of closing things down:
// Java 1.1 only protected void processWindowEvent(WindowEvent e) { if (e.getID() == WindowEvent.WINDOW_CLOSING) { // Notify others we are closing if (windowListener != null) windowListener.windowClosing(e); System.exit(0); } else { super.processEvent(e); } } If you forget to enable events, processWindowEvent() may never be called, and your windows will not shut down until the Java Virtual Machine exits. All subclasses of Frame should include code like this to make sure they terminate gracefully. Building a New Component from a WindowNow that we have discussed the Frame and Window objects, we can briefly investigate some ways to use them together. Previously I said that you can use a Window to build your own pop-up menu. That's no longer necessary in Java 1.1, but the same techniques apply to plenty of other objects. In the following example, we build a set of pop-up buttons; it also uses the Toolkit of a Frame to load images within an application. The pop-up button set appears when the user presses the right mouse button over the image. It is positioned at the coordinates of the mouseDown() event; to do so, we add the current location() of the Frame to the mouse's x and y coordinates. Figure 6.4 shows what this application looks like when the pop-up button set is on the screen.
import java.awt.*; public class PopupButtonFrame extends Frame { Image im; Window w = new PopupWindow (this); PopupButtonFrame () { super ("PopupButton Example"); resize (250, 100); show(); im = getToolkit().getImage ("rosey.jpg"); MediaTracker mt = new MediaTracker (this); mt.addImage (im, 0); try { mt.waitForAll(); } catch (Exception e) {e.printStackTrace(); } } public static void main (String args[]) { Frame f = new PopupMenuFrame (); } public void paint (Graphics g) { if (im != null) g.drawImage (im, 20, 20, this); } public boolean mouseDown (Event e, int x, int y) { if (e.modifiers == Event.META_MASK) { w.move (location().x+x, location().y+y); w.show(); return true; } return false; } } class PopupWindow extends Window { PopupWindow (Frame f) { super (f); Panel p = new Panel (); p.add (new Button ("About")); p.add (new Button ("Save")); p.add (new Button ("Quit")); add ("North", p); setBackground (Color.gray); pack(); } public boolean action (Event e, Object o) { if ("About".equals (o)) System.out.println ("About"); else if ("Save".equals (o)) System.out.println ("Save Me"); else if ("Quit".equals (o)) System.exit (0); hide(); return true; } } The most interesting method in this application is mouseDown(). When the user clicks on the mouse, mouseDown() checks whether the META_MASK is set in the event modifiers; this indicates that the user pressed the right mouse button, or pressed the left button while pressing the Meta key. If this is true, mouseDown() moves the window to the location of the mouse click, calls show() to display the window, and returns true to indicate that the event was handled completely. If mouseDown were called with any other kind of mouse event, we return false to let the event propagate to any other object that might be interested. Remember that the coordinates passed with the mouse event are the coordinates of the mouse click relative to the Frame; to find out where to position the pop-up window, we need an absolute location and therefore ask the Frame for its location. PopupWindow itself is a simple class. Its constructor simply creates a display with three buttons. The call to pack() sizes the window so that it provides a nice border around the buttons but isn't excessively large; you can change the border by playing with the window's insets if you want, but that usually isn't necessary. The class PopupWindow has an action() method that is called when the user clicks one of the buttons. When the user clicks on a button, action() prints a message and hides the window. |
|