Source for java.awt.Frame

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