GNU Classpath (0.17) | ||
Frames | No Frames |
1: /* Frame.java -- AWT toplevel window 2: Copyright (C) 1999, 2000, 2002, 2004, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package java.awt; 40: 41: import java.awt.peer.FramePeer; 42: import java.lang.ref.WeakReference; 43: import java.util.ArrayList; 44: import java.util.Iterator; 45: import java.util.Vector; 46: 47: import javax.accessibility.AccessibleContext; 48: import javax.accessibility.AccessibleRole; 49: import javax.accessibility.AccessibleState; 50: import javax.accessibility.AccessibleStateSet; 51: 52: /** 53: * This class is a top-level window with a title bar and window 54: * decorations. 55: * 56: * @author Aaron M. Renn (arenn@urbanophile.com) 57: */ 58: public class Frame extends Window implements MenuContainer 59: { 60: /** 61: * Constant for the default cursor. 62: * @deprecated Replaced by <code>Cursor.DEFAULT_CURSOR</code> instead. 63: */ 64: public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR; 65: 66: /** 67: * Constant for a cross-hair cursor. 68: * @deprecated Use <code>Cursor.CROSSHAIR_CURSOR</code> instead. 69: */ 70: public static final int CROSSHAIR_CURSOR = Cursor.CROSSHAIR_CURSOR; 71: 72: /** 73: * Constant for a cursor over a text field. 74: * @deprecated Use <code>Cursor.TEXT_CURSOR</code> instead. 75: */ 76: public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR; 77: 78: /** 79: * Constant for a cursor to display while waiting for an action to complete. 80: * @deprecated Use <code>Cursor.WAIT_CURSOR</code>. 81: */ 82: public static final int WAIT_CURSOR = Cursor.WAIT_CURSOR; 83: 84: /** 85: * Cursor used over SW corner of window decorations. 86: * @deprecated Use <code>Cursor.SW_RESIZE_CURSOR</code> instead. 87: */ 88: public static final int SW_RESIZE_CURSOR = Cursor.SW_RESIZE_CURSOR; 89: 90: /** 91: * Cursor used over SE corner of window decorations. 92: * @deprecated Use <code>Cursor.SE_RESIZE_CURSOR</code> instead. 93: */ 94: public static final int SE_RESIZE_CURSOR = Cursor.SE_RESIZE_CURSOR; 95: 96: /** 97: * Cursor used over NW corner of window decorations. 98: * @deprecated Use <code>Cursor.NW_RESIZE_CURSOR</code> instead. 99: */ 100: public static final int NW_RESIZE_CURSOR = Cursor.NW_RESIZE_CURSOR; 101: 102: /** 103: * Cursor used over NE corner of window decorations. 104: * @deprecated Use <code>Cursor.NE_RESIZE_CURSOR</code> instead. 105: */ 106: public static final int NE_RESIZE_CURSOR = Cursor.NE_RESIZE_CURSOR; 107: 108: /** 109: * Cursor used over N edge of window decorations. 110: * @deprecated Use <code>Cursor.N_RESIZE_CURSOR</code> instead. 111: */ 112: public static final int N_RESIZE_CURSOR = Cursor.N_RESIZE_CURSOR; 113: 114: /** 115: * Cursor used over S edge of window decorations. 116: * @deprecated Use <code>Cursor.S_RESIZE_CURSOR</code> instead. 117: */ 118: public static final int S_RESIZE_CURSOR = Cursor.S_RESIZE_CURSOR; 119: 120: /** 121: * Cursor used over E edge of window decorations. 122: * @deprecated Use <code>Cursor.E_RESIZE_CURSOR</code> instead. 123: */ 124: public static final int E_RESIZE_CURSOR = Cursor.E_RESIZE_CURSOR; 125: 126: /** 127: * Cursor used over W edge of window decorations. 128: * @deprecated Use <code>Cursor.W_RESIZE_CURSOR</code> instead. 129: */ 130: public static final int W_RESIZE_CURSOR = Cursor.W_RESIZE_CURSOR; 131: 132: /** 133: * Constant for a hand cursor. 134: * @deprecated Use <code>Cursor.HAND_CURSOR</code> instead. 135: */ 136: public static final int HAND_CURSOR = Cursor.HAND_CURSOR; 137: 138: /** 139: * Constant for a cursor used during window move operations. 140: * @deprecated Use <code>Cursor.MOVE_CURSOR</code> instead. 141: */ 142: public static final int MOVE_CURSOR = Cursor.MOVE_CURSOR; 143: 144: public static final int ICONIFIED = 1; 145: public static final int MAXIMIZED_BOTH = 6; 146: public static final int MAXIMIZED_HORIZ = 2; 147: public static final int MAXIMIZED_VERT = 4; 148: public static final int NORMAL = 0; 149: 150: // Serialization version constant 151: private static final long serialVersionUID = 2673458971256075116L; 152: 153: /** 154: * @serial The version of the class data being serialized 155: * // FIXME: what is this value? 156: */ 157: private int frameSerializedDataVersion; 158: 159: /** 160: * @serial Image used as the icon when this frame is minimized. 161: */ 162: private Image icon; 163: 164: /** 165: * @serial Constant used by the JDK Motif peer set. Not used in 166: * this implementation. 167: */ 168: private boolean mbManagement; 169: 170: /** 171: * @serial The menu bar for this frame. 172: */ 173: //private MenuBar menuBar = new MenuBar(); 174: private MenuBar menuBar; 175: 176: /** 177: * @serial A list of other top-level windows owned by this window. 178: */ 179: Vector ownedWindows = new Vector(); 180: 181: /** 182: * @serial Indicates whether or not this frame is resizable. 183: */ 184: private boolean resizable = true; 185: 186: /** 187: * @serial The state of this frame. 188: * // FIXME: What are the values here? 189: * This is package-private to avoid an accessor method. 190: */ 191: int state; 192: 193: /** 194: * @serial The title of the frame. 195: */ 196: private String title = ""; 197: 198: /** 199: * Maximized bounds for this frame. 200: */ 201: private Rectangle maximizedBounds; 202: 203: /** 204: * This field indicates whether the frame is undecorated or not. 205: */ 206: private boolean undecorated = false; 207: 208: /* 209: * The number used to generate the name returned by getName. 210: */ 211: private static transient long next_frame_number; 212: 213: /** 214: * Initializes a new instance of <code>Frame</code> that is not visible 215: * and has no title. 216: */ 217: public 218: Frame() 219: { 220: this(""); 221: noteFrame(this); 222: } 223: 224: /** 225: * Initializes a new instance of <code>Frame</code> that is not visible 226: * and has the specified title. 227: * 228: * @param title The title of this frame. 229: */ 230: public 231: Frame(String title) 232: { 233: super(); 234: this.title = title; 235: // Top-level frames are initially invisible. 236: visible = false; 237: noteFrame(this); 238: } 239: 240: public 241: Frame(GraphicsConfiguration gc) 242: { 243: super(gc); 244: visible = false; 245: noteFrame(this); 246: } 247: 248: public 249: Frame(String title, GraphicsConfiguration gc) 250: { 251: super(gc); 252: setTitle(title); 253: visible = false; 254: noteFrame(this); 255: } 256: 257: /** 258: * Returns this frame's title string. 259: * 260: * @return This frame's title string. 261: */ 262: public String 263: getTitle() 264: { 265: return(title); 266: } 267: 268: /* 269: * Sets this frame's title to the specified value. 270: * 271: * @param title The new frame title. 272: */ 273: public synchronized void 274: setTitle(String title) 275: { 276: this.title = title; 277: if (peer != null) 278: ((FramePeer) peer).setTitle(title); 279: } 280: 281: /** 282: * Returns this frame's icon. 283: * 284: * @return This frame's icon, or <code>null</code> if this frame does not 285: * have an icon. 286: */ 287: public Image 288: getIconImage() 289: { 290: return(icon); 291: } 292: 293: /** 294: * Sets this frame's icon to the specified value. 295: * 296: * @icon The new icon for this frame. 297: */ 298: public synchronized void 299: setIconImage(Image icon) 300: { 301: this.icon = icon; 302: if (peer != null) 303: ((FramePeer) peer).setIconImage(icon); 304: } 305: 306: /** 307: * Returns this frame's menu bar. 308: * 309: * @return This frame's menu bar, or <code>null</code> if this frame 310: * does not have a menu bar. 311: */ 312: public MenuBar 313: getMenuBar() 314: { 315: return(menuBar); 316: } 317: 318: /** 319: * Sets this frame's menu bar. 320: * 321: * @param menuBar The new menu bar for this frame. 322: */ 323: public synchronized void 324: setMenuBar(MenuBar menuBar) 325: { 326: if (peer != null) 327: { 328: if (this.menuBar != null) 329: this.menuBar.removeNotify(); 330: if (menuBar != null) 331: menuBar.addNotify(); 332: invalidateTree (); 333: ((FramePeer) peer).setMenuBar(menuBar); 334: } 335: this.menuBar = menuBar; 336: } 337: 338: /** 339: * Tests whether or not this frame is resizable. This will be 340: * <code>true</code> by default. 341: * 342: * @return <code>true</code> if this frame is resizable, <code>false</code> 343: * otherwise. 344: */ 345: public boolean 346: isResizable() 347: { 348: return(resizable); 349: } 350: 351: /** 352: * Sets the resizability of this frame to the specified value. 353: * 354: * @param resizable <code>true</code> to make the frame resizable, 355: * <code>false</code> to make it non-resizable. 356: */ 357: public synchronized void 358: setResizable(boolean resizable) 359: { 360: this.resizable = resizable; 361: if (peer != null) 362: ((FramePeer) peer).setResizable(resizable); 363: } 364: 365: /** 366: * Returns the cursor type of the cursor for this window. This will 367: * be one of the constants in this class. 368: * 369: * @return The cursor type for this frame. 370: * 371: * @deprecated Use <code>Component.getCursor()</code> instead. 372: */ 373: public int 374: getCursorType() 375: { 376: return(getCursor().getType()); 377: } 378: 379: /** 380: * Sets the cursor for this window to the specified type. The specified 381: * type should be one of the constants in this class. 382: * 383: * @param type The cursor type. 384: * 385: * @deprecated Use <code>Component.setCursor(Cursor)</code> instead. 386: */ 387: public void 388: setCursor(int type) 389: { 390: setCursor(new Cursor(type)); 391: } 392: 393: /** 394: * Removes the specified component from this frame's menu. 395: * 396: * @param menu The menu component to remove. 397: */ 398: public void 399: remove(MenuComponent menu) 400: { 401: menuBar.remove(menu); 402: } 403: 404: /** 405: * Notifies this frame that it should create its native peer. 406: */ 407: private static void fireDummyEvent() 408: { 409: EventQueue.invokeLater(new Runnable() 410: { 411: public void run() 412: { 413: // Do nothing here. 414: } 415: }); 416: } 417: 418: public void 419: addNotify() 420: { 421: if (menuBar != null) 422: menuBar.addNotify(); 423: if (peer == null) 424: peer = getToolkit ().createFrame (this); 425: 426: // We now know there's a Frame (us) with a live peer, so we can start the 427: // fundamental queue and dispatch thread, by inserting a dummy event. 428: if (parent != null && parent.isDisplayable()) 429: fireDummyEvent(); 430: 431: super.addNotify(); 432: } 433: 434: public void removeNotify() 435: { 436: if (menuBar != null) 437: menuBar.removeNotify(); 438: super.removeNotify(); 439: 440: // By now we've been disconnected from the peer, and the peer set to 441: // null. This is formally the same as saying "we just became 442: // un-displayable", so we wake up the event queue with a dummy event to 443: // see if it's time to shut down. 444: fireDummyEvent(); 445: } 446: 447: /** 448: * Returns a debugging string describing this window. 449: * 450: * @return A debugging string describing this window. 451: */ 452: protected String paramString () 453: { 454: String title = getTitle (); 455: 456: String resizable = ""; 457: if (isResizable ()) 458: resizable = ",resizable"; 459: 460: String state = ""; 461: switch (getState ()) 462: { 463: case NORMAL: 464: state = ",normal"; 465: break; 466: case ICONIFIED: 467: state = ",iconified"; 468: break; 469: case MAXIMIZED_BOTH: 470: state = ",maximized-both"; 471: break; 472: case MAXIMIZED_HORIZ: 473: state = ",maximized-horiz"; 474: break; 475: case MAXIMIZED_VERT: 476: state = ",maximized-vert"; 477: break; 478: } 479: 480: return super.paramString () + ",title=" + title + resizable + state; 481: } 482: 483: private static ArrayList weakFrames = new ArrayList(); 484: 485: private static void noteFrame(Frame f) 486: { 487: weakFrames.add(new WeakReference(f)); 488: } 489: 490: public static Frame[] getFrames() 491: { 492: int n = 0; 493: synchronized (weakFrames) 494: { 495: Iterator i = weakFrames.iterator(); 496: while (i.hasNext()) 497: { 498: WeakReference wr = (WeakReference) i.next(); 499: if (wr.get() != null) 500: ++n; 501: } 502: if (n == 0) 503: return new Frame[0]; 504: else 505: { 506: Frame[] frames = new Frame[n]; 507: n = 0; 508: i = weakFrames.iterator(); 509: while (i.hasNext()) 510: { 511: WeakReference wr = (WeakReference) i.next(); 512: if (wr.get() != null) 513: frames[n++] = (Frame) wr.get(); 514: } 515: return frames; 516: } 517: } 518: } 519: 520: public void setState (int state) 521: { 522: int current_state = getExtendedState (); 523: 524: if (state == NORMAL 525: && (current_state & ICONIFIED) != 0) 526: setExtendedState (current_state | ICONIFIED); 527: 528: if (state == ICONIFIED 529: && (current_state & ~ICONIFIED) == 0) 530: setExtendedState (current_state & ~ICONIFIED); 531: } 532: 533: public int getState () 534: { 535: /* FIXME: State might have changed in the peer... Must check. */ 536: 537: return (state & ICONIFIED) != 0 ? ICONIFIED : NORMAL; 538: } 539: 540: /** 541: * @since 1.4 542: */ 543: public void setExtendedState (int state) 544: { 545: this.state = state; 546: } 547: 548: /** 549: * @since 1.4 550: */ 551: public int getExtendedState () 552: { 553: return state; 554: } 555: 556: /** 557: * @since 1.4 558: */ 559: public void setMaximizedBounds (Rectangle maximizedBounds) 560: { 561: this.maximizedBounds = maximizedBounds; 562: } 563: 564: /** 565: * Returns the maximized bounds of this frame. 566: * 567: * @return the maximized rectangle, may be null. 568: * 569: * @since 1.4 570: */ 571: public Rectangle getMaximizedBounds () 572: { 573: return maximizedBounds; 574: } 575: 576: /** 577: * Returns whether this frame is undecorated or not. 578: * 579: * @since 1.4 580: */ 581: public boolean isUndecorated () 582: { 583: return undecorated; 584: } 585: 586: /** 587: * Disables or enables decorations for this frame. This method can only be 588: * called while the frame is not displayable. 589: * 590: * @exception IllegalComponentStateException If this frame is displayable. 591: * 592: * @since 1.4 593: */ 594: public void setUndecorated (boolean undecorated) 595: { 596: if (isDisplayable ()) 597: throw new IllegalComponentStateException (); 598: 599: this.undecorated = undecorated; 600: } 601: 602: /** 603: * Generate a unique name for this frame. 604: * 605: * @return A unique name for this frame. 606: */ 607: String generateName () 608: { 609: return "frame" + getUniqueLong (); 610: } 611: 612: private static synchronized long getUniqueLong () 613: { 614: return next_frame_number++; 615: } 616: 617: protected class AccessibleAWTFrame extends AccessibleAWTWindow 618: { 619: public AccessibleRole getAccessibleRole() 620: { 621: return AccessibleRole.FRAME; 622: } 623: 624: public AccessibleStateSet getAccessibleState() 625: { 626: AccessibleStateSet states = super.getAccessibleStateSet(); 627: if (isResizable()) 628: states.add(AccessibleState.RESIZABLE); 629: if ((state & ICONIFIED) != 0) 630: states.add(AccessibleState.ICONIFIED); 631: return states; 632: } 633: } 634: 635: /** 636: * Gets the AccessibleContext associated with this <code>Frame</code>. 637: * The context is created, if necessary. 638: * 639: * @return the associated context 640: */ 641: public AccessibleContext getAccessibleContext() 642: { 643: /* Create the context if this is the first request */ 644: if (accessibleContext == null) 645: accessibleContext = new AccessibleAWTFrame(); 646: return accessibleContext; 647: } 648: 649: }
GNU Classpath (0.17) |