Source for java.awt.Frame

   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: }