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