001: /*
002: * @(#)Frame.java 1.10 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: /*
029: * Warning :
030: * Two versions of this file exist in this workspace.
031: * One for Personal Basis, and one for Personal Profile.
032: * Don't edit the wrong one !!!
033: */
034:
035: package java.awt;
036:
037: import java.awt.event.*;
038: import sun.awt.AppContext;
039: import java.util.Vector;
040: import java.io.ObjectOutputStream;
041: import java.io.ObjectInputStream;
042: import java.io.IOException;
043: import java.lang.ref.WeakReference;
044: import javax.swing.JMenuBar;
045:
046: /**
047: * A Frame is window with additional properties, such as a title bar,
048: * a menu bar, a cursor, and an icon image where appropriate.
049: * A Personal Profile implementation is not required to support multiple
050: * frames. It must allow at least one frame to be created then it may
051: * throw an <em>UnsupportedOperationException</em> on subsequent <code>Frame</code> creations.
052: * <p>
053: * <li>The Title Property
054: * The title property can be set when the frame is created and changed
055: * at any time. How the title property is displayed and used is platform dependent.
056: * <li>The Resizable Property
057: * The Resizable property determines if a frame can be resized by the
058: * user. Personal Profile and PersonalJava, implementations are not required
059: * to support resizable frames.
060: * <li>The Cursor Property
061: * Not all cursors may be supported
062: * <h3>System Properties</h3>
063: * <code>java.awt.frame.SupportsMultipleFrames</code> "true" if the Personal Profile
064: * implementation supports multiple frames, otherwise "false".
065: * <p>
066: * <code>java.awt.frame.SupportsResizable</code> "true" if the Personal Profile
067: * implementation supports resizable frames, otherwise "false".
068: *
069: * @version 1.6, 08/19/02
070: * @author Nicholas Allen
071: * @see WindowEvent
072: * @see Window#addWindowListener
073: * @since JDK1.0
074: */
075: public class Frame extends Window implements MenuContainer {
076: /* Note: These are being obsoleted; programs should use the Cursor class
077: * variables going forward. See Cursor and Component.setCursor.
078: */
079:
080: /**
081: *
082: */
083: public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR;
084: /**
085: *
086: */
087: public static final int CROSSHAIR_CURSOR = Cursor.CROSSHAIR_CURSOR;
088: /**
089: *
090: */
091: public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR;
092: /**
093: *
094: */
095: public static final int WAIT_CURSOR = Cursor.WAIT_CURSOR;
096: /**
097: *
098: */
099: public static final int SW_RESIZE_CURSOR = Cursor.SW_RESIZE_CURSOR;
100: /**
101: *
102: */
103: public static final int SE_RESIZE_CURSOR = Cursor.SE_RESIZE_CURSOR;
104: /**
105: *
106: */
107: public static final int NW_RESIZE_CURSOR = Cursor.NW_RESIZE_CURSOR;
108: /**
109: *
110: */
111: public static final int NE_RESIZE_CURSOR = Cursor.NE_RESIZE_CURSOR;
112: /**
113: *
114: */
115: public static final int N_RESIZE_CURSOR = Cursor.N_RESIZE_CURSOR;
116: /**
117: *
118: */
119: public static final int S_RESIZE_CURSOR = Cursor.S_RESIZE_CURSOR;
120: /**
121: *
122: */
123: public static final int W_RESIZE_CURSOR = Cursor.W_RESIZE_CURSOR;
124: /**
125: *
126: */
127: public static final int E_RESIZE_CURSOR = Cursor.E_RESIZE_CURSOR;
128: /**
129: *
130: */
131: public static final int HAND_CURSOR = Cursor.HAND_CURSOR;
132: /**
133: *
134: */
135: public static final int MOVE_CURSOR = Cursor.MOVE_CURSOR;
136: String title = "Untitled";
137: Image icon;
138: MenuBar menuBar;
139: boolean resizable = true;
140: boolean mbManagement = false; /* used only by the Motif impl. */
141: /*
142: * The Windows owned by the Frame.
143: */
144: Vector ownedWindows;
145: private static final String base = "frame";
146: private static int nameCounter = 0;
147: /*
148: * JDK 1.1 serialVersionUID
149: */
150: private static final long serialVersionUID = 2673458971256075116L;
151:
152: /**
153: * Constructs a new <code>Frame</code>
154: * <h3>Compatibility</h3>
155: * A Personal Profile implementation is not required to support multiple
156: * Frames (the current Frame must be destroyed before a subsequent Frame
157: * can be created). Support for menu objects is independent of the level
158: * of Frame support.
159: * <p>
160: * A PersonalJava implementation, which fully supported Frame, also
161: * supported CheckBoxMenuItem, Menu, MenuBar and MenuShortcut.
162: * JDK Fully supports multiple frames.
163: * @exception UnsupportedOperationException if multiple frames are created
164: * on a platform which only supports a single frame.
165: * @see Component#setSize
166: * @see Component#setVisible
167: * @since JDK1.0
168: */
169: public Frame() {
170: this ("");
171: }
172:
173: /**
174: * Constructs a new <code>Frame</code>
175: * <h3>Compatibility</h3>
176: * A Personal Profile implementation is not required to support multiple
177: * Frames (the current Frame must be destroyed before a subsequent Frame
178: * can be created). Support for menu objects is independent of the level
179: * of Frame support.
180: * <p>
181: * A PersonalJava implementation, which fully supported Frame, also
182: * supported CheckBoxMenuItem, Menu, MenuBar and MenuShortcut.
183: * JDK Fully supports multiple frames.
184: * @param title is the string specifying the frames title.
185: * @exception UnsupportedOperationException if multiple frames are created
186: * on a platform which only supports a single frame.
187: * @see java.awt.Component#setSize
188: * @see java.awt.Component#setVisible
189: * @since JDK1.0
190: */
191: public Frame(String title) {
192: this .title = title;
193: visible = false;
194: setLayout(new BorderLayout());
195: }
196:
197: /**
198: * Construct a name for this component. Called by getName() when the
199: * name is null.
200: */
201: String constructComponentName() {
202: return base + nameCounter++;
203: }
204:
205: /**
206: * Adds the specified window to the list of windows owned by
207: * the frame.
208: * @param window the window to be added
209: */
210: Window addOwnedWindow(Window window) {
211: if (window != null) {
212: if (ownedWindows == null) {
213: ownedWindows = new Vector();
214: }
215: ownedWindows.addElement(window);
216: }
217: return window;
218: }
219:
220: /**
221: * Removes the specified window from the list of windows owned by
222: * the frame.
223: * @param window the window to be added
224: */
225: void removeOwnedWindow(Window window) {
226: if (window != null) {
227: if (ownedWindows != null) {
228: ownedWindows.removeElement(window);
229: }
230: }
231: }
232:
233: ComponentXWindow createXWindow() {
234: return new FrameXWindow(this );
235: }
236:
237: public Graphics getGraphics() {
238: Graphics g = super .getGraphics();
239: // Clip graphics so cannot draw in menu bar area
240:
241: if (g != null && menuBar != null) {
242: Insets insets = getInsets();
243: g.clipRect(0, insets.top, width, height);
244: }
245: return g;
246: }
247:
248: public void addNotify() {
249: super .addNotify();
250: MenuBar menuBar = this .menuBar;
251: if (menuBar != null)
252: menuBar.addNotify();
253: }
254:
255: public void removeNotify() {
256: super .removeNotify();
257: MenuBar menuBar = this .menuBar;
258: if (menuBar != null)
259: menuBar.removeNotify();
260: }
261:
262: /**
263: * Gets the title of the frame.
264: * @return the title of this frame, or <code>null</code>
265: * if this frame doesn't have a title.
266: * @see java.awt.Frame#setTitle
267: * @since JDK1.0
268: */
269: public String getTitle() {
270: return title;
271: }
272:
273: /**
274: * Sets the title for this frame to the specified title.
275: * @param title the specified title of this frame.
276: * @see java.awt.Frame#getTitle
277: * @since JDK1.0
278: */
279: public synchronized void setTitle(String title) {
280: this .title = title;
281: FrameXWindow xwindow = (FrameXWindow) this .xwindow;
282: if (xwindow != null) {
283: xwindow.setTitle(title);
284: }
285: }
286:
287: /**
288: * Gets the icon image for this frame.
289: * @return the icon image for this frame, or <code>null</code>
290: * if this frame doesn't have an icon image.
291: * @see java.awt.Frame#setIconImage
292: * @since JDK1.0
293: */
294: public Image getIconImage() {
295: return icon;
296: }
297:
298: public Insets getInsets() {
299: Insets insets = super .getInsets();
300: if (menuBar != null)
301: insets.top += menuBar.jMenuBar.getHeight();
302: return insets;
303: }
304:
305: public void validate() {
306: MenuBar menuBar = this .menuBar;
307: if (menuBar != null) {
308: Insets insets = super .getInsets();
309: menuBar.jMenuBar.setBounds(insets.left, insets.top, width
310: - insets.left - insets.right, menuBar.jMenuBar
311: .getPreferredSize().height);
312: menuBar.jMenuBar.validate();
313: }
314: super .validate();
315: }
316:
317: void dispatchEventImpl(AWTEvent e) {
318: super .dispatchEventImpl(e);
319: // Paint the JMenuBar if a menubar is attatched to this frame.
320:
321: if (e instanceof PaintEvent) {
322: PaintEvent paintEvent = (PaintEvent) e;
323: MenuBar menuBar = this .menuBar;
324: if (menuBar != null) {
325: // Get super graphics because our graphics is clipped to prevent drawing
326: // in the menu bar area.
327:
328: Graphics g = super .getGraphics();
329: if (g != null) {
330: Rectangle clip = paintEvent.getUpdateRect();
331: g.clipRect(clip.x, clip.y, clip.width, clip.height);
332: Component c = menuBar.jMenuBar;
333: Graphics cg = g.create(c.x, c.y, c.width, c.height);
334: try {
335: c.paint(cg);
336: } finally {
337: cg.dispose();
338: g.dispose();
339: Toolkit.getDefaultToolkit().sync();
340: }
341: }
342: }
343: }
344: }
345:
346: /**
347: * Sets the image to display when this frame is iconized.
348: * Not all platforms support the concept of iconizing a window.
349: * @param image the icon image to be displayed
350: * @see java.awt.Frame#getIconImage
351: * @since JDK1.0
352: */
353: public synchronized void setIconImage(Image image) {
354: this .icon = image;
355: FrameXWindow xwindow = (FrameXWindow) this .xwindow;
356: if (xwindow != null) {
357: xwindow.setIconImage(image);
358: }
359: }
360:
361: /**
362: * Gets the menu bar for this frame.
363: * @return the menu bar for this frame, or <code>null</code>
364: * if this frame doesn't have a menu bar.
365: * @see java.awt.Frame#setMenuBar
366: * @since JDK1.0
367: */
368: public MenuBar getMenuBar() {
369: return menuBar;
370: }
371:
372: /**
373:
374: * Sets this Frame's menu bar.
375: * <h3>Compatability</h3>
376: * In PersonalJava and PersonalProfile, this operation is optional and throws an
377: * UnsupportedOperationException if it is not supported.
378: * @param mb the menu bar being set
379: * @exception UnsupportedOperationException if it is not supported.
380: * @see java.awt.Frame#getMenuBar
381: * @see java.awt.MenuBar
382: * @since JDK1.0
383: */
384: public void setMenuBar(MenuBar mb) {
385: synchronized (getTreeLock()) {
386: if (menuBar == mb) {
387: return;
388: }
389: if (menuBar != null) {
390: remove(menuBar);
391: }
392: menuBar = mb;
393: if (mb != null) {
394: if (mb.parent != null)
395: mb.parent.remove(mb);
396: mb.parent = this ;
397: if (xwindow != null)
398: mb.addNotify();
399: }
400: EventQueue.invokeLater(new Runnable() {
401: public void run() {
402: invalidate();
403: validate();
404: }
405: });
406: }
407: }
408:
409: /**
410: * Indicates whether this frame is resizable.
411: * By default, all frames are initially resizable.
412: * @return <code>true</code> if the user can resize this frame;
413: * <code>false</code> otherwise.
414: * @see java.awt.Frame#setResizable
415: * @since JDK1.0
416: */
417: public boolean isResizable() {
418: return resizable;
419: }
420:
421: /**
422: * Sets the resizable Property
423: * <h3>Compatability</h3>
424: * In Personal Profile this method can have no effect. The
425: * <code>isResizable()</code> method may be used to verify this.
426: * Also the system property java.awt.frame.SupportsResizable is
427: * <code>"true"</code> if the platform supports resizable frames.
428: * @param resizable if <code>true</code>, the frame becomes resizable,
429: * otherwise the frame become non resizable.
430: * @see java.awt.Frame#isResizable
431: * @since JDK1.0
432: */
433: public synchronized void setResizable(boolean resizable) {
434: this .resizable = resizable;
435: FrameXWindow xwindow = (FrameXWindow) this .xwindow;
436: if (xwindow != null) {
437: xwindow.setResizable(resizable);
438: }
439: }
440:
441: /**
442: * Removes the specified menu bar from this frame.
443: * @param m the menu component to remove.
444: * @since JDK1.0
445: */
446: public void remove(MenuComponent m) {
447: synchronized (getTreeLock()) {
448: if (m != null && m == menuBar) {
449: menuBar.parent = null;
450: menuBar = null;
451: if (xwindow != null)
452: m.removeNotify();
453: } else {
454: super .remove(m);
455: }
456: }
457: }
458:
459: /**
460: * Disposes of the Frame. This method must
461: * be called to release the resources that
462: * are used for the frame. All components
463: * contained by the frame and all windows
464: * owned by the frame will also be destroyed.
465: * @since JDK1.0
466: */
467: public void dispose() { // synch removed.
468: synchronized (getTreeLock()) {
469: if (ownedWindows != null) {
470: int ownedWindowCount = ownedWindows.size();
471: Window ownedWindowCopy[] = new Window[ownedWindowCount];
472: ownedWindows.copyInto(ownedWindowCopy);
473: for (int i = 0; i < ownedWindowCount; i++) {
474: ownedWindowCopy[i].dispose();
475: }
476: }
477: if (menuBar != null) {
478: remove(menuBar);
479: menuBar = null;
480: }
481: }
482: super .dispose();
483: }
484:
485: void postProcessKeyEvent(KeyEvent e) {
486: if (menuBar != null && menuBar.handleShortcut(e)) {
487: e.consume();
488: return;
489: }
490: super .postProcessKeyEvent(e);
491: }
492:
493: /**
494: * Returns the parameter String of this Frame.
495: */
496: protected String paramString() {
497: String str = super .paramString();
498: if (resizable) {
499: str += ",resizable";
500: }
501: if (title != null) {
502: str += ",title=" + title;
503: }
504: return str;
505: }
506:
507: /**
508: * @deprecated As of JDK version 1.1,
509: * replaced by <code>Component.setCursor(Cursor)</code>.
510: */
511: public synchronized void setCursor(int cursorType) {
512: if (cursorType < DEFAULT_CURSOR || cursorType > MOVE_CURSOR) {
513: throw new IllegalArgumentException("illegal cursor type");
514: }
515: setCursor(Cursor.getPredefinedCursor(cursorType));
516: }
517:
518: /**
519: * @deprecated As of JDK version 1.1,
520: * replaced by <code>Component.getCursor()</code>.
521: */
522: public int getCursorType() {
523: return (getCursor().getType());
524: }
525:
526: /**
527: * Returns an array containing all Frames created by the application.
528: * If called from an applet, the array will only include the Frames
529: * accessible by that applet.
530: * @since 1.2
531: */
532: public static Frame[] getFrames() {
533: synchronized (Frame.class) {
534: Frame realCopy[];
535: Vector frameList = (Vector) AppContext.getAppContext().get(
536: Frame.class);
537: if (frameList != null) {
538: // Recall that frameList is actually a Vector of WeakReferences
539: // and calling get() on one of these references may return
540: // null. Make two arrays-- one the size of the Vector
541: // (fullCopy with size fullSize), and one the size of all
542: // non-null get()s (realCopy with size realSize).
543: int fullSize = frameList.size();
544: int realSize = 0;
545: Frame fullCopy[] = new Frame[fullSize];
546: for (int i = 0; i < fullSize; i++) {
547: fullCopy[realSize] = (Frame) (((WeakReference) (frameList
548: .elementAt(i))).get());
549: if (fullCopy[realSize] != null) {
550: realSize++;
551: }
552: }
553: if (fullSize != realSize) {
554: realCopy = new Frame[realSize];
555: System
556: .arraycopy(fullCopy, 0, realCopy, 0,
557: realSize);
558: } else {
559: realCopy = fullCopy;
560: }
561: } else {
562: realCopy = new Frame[0];
563: }
564: return realCopy;
565: }
566: }
567:
568: /* Serialization support. If there's a MenuBar we restore
569: * its (transient) parent field here. Likewise for top level
570: * windows that are "owned" by this frame.
571: */
572:
573: private int frameSerializedDataVersion = 1;
574:
575: private void writeObject(ObjectOutputStream s) throws IOException {
576: s.defaultWriteObject();
577: }
578:
579: private void readObject(ObjectInputStream s)
580: throws ClassNotFoundException, IOException {
581: s.defaultReadObject();
582: if (menuBar != null)
583: menuBar.parent = this ;
584: if (ownedWindows != null) {
585: for (int i = 0; i < ownedWindows.size(); i++) {
586: Window child = (Window) (ownedWindows.elementAt(i));
587: child.parent = this;
588: }
589: }
590: }
591: }
|