Source for java.awt.Window

   1: /* Window.java --
   2:    Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005  Free Software Foundation
   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.event.ComponentEvent;
  42: import java.awt.event.WindowEvent;
  43: import java.awt.event.WindowFocusListener;
  44: import java.awt.event.WindowListener;
  45: import java.awt.event.WindowStateListener;
  46: import java.awt.image.BufferStrategy;
  47: import java.awt.peer.WindowPeer;
  48: import java.lang.ref.Reference;
  49: import java.lang.ref.WeakReference;
  50: import java.util.EventListener;
  51: import java.util.Iterator;
  52: import java.util.Locale;
  53: import java.util.ResourceBundle;
  54: import java.util.Vector;
  55: 
  56: import javax.accessibility.Accessible;
  57: import javax.accessibility.AccessibleContext;
  58: import javax.accessibility.AccessibleRole;
  59: import javax.accessibility.AccessibleState;
  60: import javax.accessibility.AccessibleStateSet;
  61: 
  62: /**
  63:  * This class represents a top-level window with no decorations.
  64:  *
  65:  * @author Aaron M. Renn (arenn@urbanophile.com)
  66:  * @author Warren Levy  (warrenl@cygnus.com)
  67:  */
  68: public class Window extends Container implements Accessible
  69: {
  70:   private static final long serialVersionUID = 4497834738069338734L;
  71: 
  72:   // Serialized fields, from Sun's serialization spec.
  73:   private String warningString = null;
  74:   private int windowSerializedDataVersion = 0; // FIXME
  75:   /** @since 1.2 */
  76:   // private FocusManager focusMgr;  // FIXME: what is this?  
  77:   /** @since 1.2 */
  78:   private int state = 0;
  79:   /** @since 1.4 */
  80:   private boolean focusableWindowState = true;
  81:   /** @since 1.5 */
  82:   private boolean alwaysOnTop = false;
  83: 
  84:   // A list of other top-level windows owned by this window.
  85:   private transient Vector ownedWindows = new Vector();
  86: 
  87:   private transient WindowListener windowListener;
  88:   private transient WindowFocusListener windowFocusListener;
  89:   private transient WindowStateListener windowStateListener;
  90: 
  91:   private transient boolean shown;
  92: 
  93:   // This is package-private to avoid an accessor method.
  94:   transient Component windowFocusOwner;
  95:   
  96:   /*
  97:    * The number used to generate the name returned by getName.
  98:    */
  99:   private static transient long next_window_number;
 100: 
 101:   protected class AccessibleAWTWindow extends AccessibleAWTContainer
 102:   {
 103:     private static final long serialVersionUID = 4215068635060671780L;
 104: 
 105:     public AccessibleRole getAccessibleRole()
 106:     {
 107:       return AccessibleRole.WINDOW;
 108:     }
 109:     
 110:     public AccessibleStateSet getAccessibleStateSet()
 111:     {
 112:       AccessibleStateSet states = super.getAccessibleStateSet();
 113:       if (isActive())
 114:         states.add(AccessibleState.ACTIVE);
 115:       return states;
 116:     }
 117:   }
 118: 
 119:   /** 
 120:    * This (package access) constructor is used by subclasses that want
 121:    * to build windows that do not have parents.  Eg. toplevel
 122:    * application frames.  Subclasses cannot call super(null), since
 123:    * null is an illegal argument.
 124:    */
 125:   Window()
 126:   {
 127:     visible = false;
 128:     // Windows are the only Containers that default to being focus
 129:     // cycle roots.
 130:     focusCycleRoot = true;
 131:     setLayout(new BorderLayout());
 132:     
 133:     GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment();
 134:     graphicsConfig = g.getDefaultScreenDevice().getDefaultConfiguration();
 135:   }
 136: 
 137:   Window(GraphicsConfiguration gc)
 138:   {
 139:     this();
 140:     graphicsConfig = gc;
 141:   }
 142: 
 143:   /**
 144:    * Initializes a new instance of <code>Window</code> with the specified
 145:    * parent.  The window will initially be invisible.
 146:    *
 147:    * @param owner The owning <code>Frame</code> of this window.
 148:    *
 149:    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
 150:    * is not from a screen device, or if owner is null; this exception is always
 151:    * thrown when GraphicsEnvironment.isHeadless returns true.
 152:    */
 153:   public Window(Frame owner)
 154:   {
 155:     this (owner, owner.getGraphicsConfiguration ());
 156:   }
 157: 
 158:   /**
 159:    * Initializes a new instance of <code>Window</code> with the specified
 160:    * parent.  The window will initially be invisible.   
 161:    *
 162:    * @exception IllegalArgumentException If the owner's GraphicsConfiguration
 163:    * is not from a screen device, or if owner is null; this exception is always
 164:    * thrown when GraphicsEnvironment.isHeadless returns true.
 165:    *
 166:    * @since 1.2
 167:    */
 168:   public Window(Window owner)
 169:   {
 170:     this (owner, owner.getGraphicsConfiguration ());
 171:   }
 172:   
 173:   /**
 174:    * Initializes a new instance of <code>Window</code> with the specified
 175:    * parent.  The window will initially be invisible.   
 176:    *
 177:    * @exception IllegalArgumentException If owner is null or if gc is not from a
 178:    * screen device; this exception is always thrown when
 179:    * GraphicsEnvironment.isHeadless returns true.
 180:    *
 181:    * @since 1.3
 182:    */
 183:   public Window(Window owner, GraphicsConfiguration gc)
 184:   {
 185:     this ();
 186: 
 187:     synchronized (getTreeLock())
 188:       {
 189:     if (owner == null)
 190:       throw new IllegalArgumentException ("owner must not be null");
 191: 
 192:     parent = owner;
 193:         owner.ownedWindows.add(new WeakReference(this));
 194:       }
 195: 
 196:     // FIXME: make this text visible in the window.
 197:     SecurityManager s = System.getSecurityManager();
 198:     if (s != null && ! s.checkTopLevelWindow(this))
 199:       warningString = System.getProperty("awt.appletWarning");
 200: 
 201:     if (gc != null
 202:         && gc.getDevice().getType() != GraphicsDevice.TYPE_RASTER_SCREEN)
 203:       throw new IllegalArgumentException ("gc must be from a screen device");
 204: 
 205:     if (gc == null)
 206:       graphicsConfig = GraphicsEnvironment.getLocalGraphicsEnvironment()
 207:                                           .getDefaultScreenDevice()
 208:                                           .getDefaultConfiguration();
 209:     else
 210:       graphicsConfig = gc;
 211:   }
 212: 
 213:   /**
 214:    * Creates the native peer for this window.
 215:    */
 216:   public void addNotify()
 217:   {
 218:     if (peer == null)
 219:       peer = getToolkit().createWindow(this);
 220:     super.addNotify();
 221:   }
 222: 
 223:   /**
 224:    * Relays out this window's child components at their preferred size.
 225:    *
 226:    * @specnote pack() doesn't appear to be called internally by show(), so
 227:    *             we duplicate some of the functionality.
 228:    */
 229:   public void pack()
 230:   {
 231:     if (parent != null && !parent.isDisplayable())
 232:       parent.addNotify();
 233:     if (peer == null)
 234:       addNotify();
 235: 
 236:     setSize(getPreferredSize());
 237: 
 238:     validate();
 239:   }
 240: 
 241:   /**
 242:    * Shows on-screen this window and any of its owned windows for whom
 243:    * isVisible returns true.
 244:    * @specnote: Deprecated starting in 1.5.
 245:    */
 246:   @Deprecated
 247:   public void show()
 248:   {
 249:     synchronized (getTreeLock())
 250:       {
 251:         if (peer == null)
 252:           addNotify();
 253: 
 254:         validate();
 255:         if (visible)
 256:           toFront();
 257:         else
 258:           {
 259:             super.show();
 260:             // Show visible owned windows.
 261:             Iterator e = ownedWindows.iterator();
 262:             while (e.hasNext())
 263:               {
 264:                 Window w = (Window) (((Reference) e.next()).get());
 265:                 if (w != null)
 266:                   {
 267:                     if (w.isVisible())
 268:                       w.getPeer().setVisible(true);
 269:                   }
 270:                 else
 271:                   // Remove null weak reference from ownedWindows.
 272:                   // Unfortunately this can't be done in the Window's
 273:                   // finalize method because there is no way to guarantee
 274:                   // synchronous access to ownedWindows there.
 275:                   e.remove();
 276:               }
 277:           }
 278:         KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
 279:         manager.setGlobalFocusedWindow(this);
 280: 
 281:         if (! shown)
 282:           {
 283:             FocusTraversalPolicy policy = getFocusTraversalPolicy();
 284:             Component initialFocusOwner = null;
 285: 
 286:             if (policy != null)
 287:               initialFocusOwner = policy.getInitialComponent(this);
 288: 
 289:             if (initialFocusOwner != null)
 290:               initialFocusOwner.requestFocusInWindow();
 291: 
 292:             // Post WINDOW_OPENED from here.
 293:             if (windowListener != null
 294:                 || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0)
 295:               {
 296:                 WindowEvent ev = new WindowEvent(this,
 297:                                                  WindowEvent.WINDOW_OPENED);
 298:                 Toolkit tk = Toolkit.getDefaultToolkit();
 299:                 tk.getSystemEventQueue().postEvent(ev);
 300:               }
 301:             shown = true;
 302:           }
 303:       }
 304:   }
 305: 
 306:   /**
 307:    * @specnote: Deprecated starting in 1.5.
 308:    */
 309:   @Deprecated
 310:   public void hide()
 311:   {
 312:     // Hide visible owned windows.
 313:     synchronized (getTreeLock ())
 314:       {
 315:     Iterator e = ownedWindows.iterator();
 316:     while(e.hasNext())
 317:       {
 318:         Window w = (Window)(((Reference) e.next()).get());
 319:         if (w != null)
 320:           {
 321:         if (w.isVisible() && w.getPeer() != null)
 322:           w.getPeer().setVisible(false);
 323:           }
 324:              else
 325:           e.remove();
 326:       }
 327:       }
 328:     super.hide();
 329:   }
 330: 
 331:   /**
 332:    * Destroys any resources associated with this window.  This includes
 333:    * all components in the window and all owned top-level windows.
 334:    */
 335:   public void dispose()
 336:   {
 337:     hide();
 338: 
 339:     synchronized (getTreeLock ())
 340:       {
 341:     Iterator e = ownedWindows.iterator();
 342:     while(e.hasNext())
 343:       {
 344:         Window w = (Window)(((Reference) e.next()).get());
 345:         if (w != null)
 346:           w.dispose();
 347:         else
 348:           // Remove null weak reference from ownedWindows.
 349:           e.remove();
 350:       }
 351: 
 352:     for (int i = 0; i < ncomponents; ++i)
 353:       component[i].removeNotify();
 354:     this.removeNotify();
 355: 
 356:     // Post WINDOW_CLOSED from here.
 357:     if (windowListener != null
 358:         || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0)
 359:       {
 360:         WindowEvent ev = new WindowEvent(this,
 361:                                          WindowEvent.WINDOW_CLOSED);
 362:         Toolkit tk = Toolkit.getDefaultToolkit();
 363:         tk.getSystemEventQueue().postEvent(ev);
 364:       }
 365:       }
 366:   }
 367: 
 368:   /**
 369:    * Sends this window to the back so that all other windows display in
 370:    * front of it.
 371:    *
 372:    * If the window is set to be always-on-top, this will remove its
 373:    * always-on-top status.
 374:    */
 375:   public void toBack()
 376:   {
 377:     if (peer != null)
 378:       {
 379:     if( alwaysOnTop )
 380:       setAlwaysOnTop( false );
 381:     ( (WindowPeer) peer ).toBack();
 382:       }
 383:   }
 384: 
 385:   /**
 386:    * Brings this window to the front so that it displays in front of
 387:    * any other windows.
 388:    */
 389:   public void toFront()
 390:   {
 391:     if (peer != null)
 392:       ( (WindowPeer) peer ).toFront();
 393:   }
 394: 
 395:   /**
 396:    * Returns the toolkit used to create this window.
 397:    *
 398:    * @return The toolkit used to create this window.
 399:    *
 400:    * @specnote Unlike Component.getToolkit, this implementation always 
 401:    *           returns the value of Toolkit.getDefaultToolkit().
 402:    */
 403:   public Toolkit getToolkit()
 404:   {
 405:     return Toolkit.getDefaultToolkit();    
 406:   }
 407: 
 408:   /**
 409:    * Returns the warning string that will be displayed if this window is
 410:    * popped up by an unsecure applet or application.
 411:    *
 412:    * @return The unsecure window warning message.
 413:    */
 414:   public final String getWarningString()
 415:   {
 416:     return warningString;
 417:   }
 418: 
 419:   /**
 420:    * Returns the locale that this window is configured for.
 421:    *
 422:    * @return The locale this window is configured for.
 423:    */
 424:   public Locale getLocale()
 425:   {
 426:     return locale == null ? Locale.getDefault() : locale;
 427:   }
 428: 
 429:   /*
 430:   /** @since 1.2
 431:   public InputContext getInputContext()
 432:   {
 433:     // FIXME
 434:   }
 435:   */
 436: 
 437:   /**
 438:    * Sets the cursor for this window to the specifiec cursor.
 439:    *
 440:    * @param cursor The new cursor for this window.
 441:    */
 442:   public void setCursor(Cursor cursor)
 443:   {
 444:     super.setCursor(cursor);
 445:   }
 446: 
 447:   public Window getOwner()
 448:   {
 449:     return (Window) parent;
 450:   }
 451: 
 452:   /** @since 1.2 */
 453:   public Window[] getOwnedWindows()
 454:   {
 455:     Window [] trimmedList;
 456:     synchronized (getTreeLock ())
 457:       {
 458:     // Windows with non-null weak references in ownedWindows.
 459:     Window [] validList = new Window [ownedWindows.size()];
 460: 
 461:     Iterator e = ownedWindows.iterator();
 462:     int numValid = 0;
 463:     while (e.hasNext())
 464:       {
 465:         Window w = (Window)(((Reference) e.next()).get());
 466:         if (w != null)
 467:           validList[numValid++] = w;
 468:         else
 469:           // Remove null weak reference from ownedWindows.
 470:           e.remove();
 471:       }
 472: 
 473:     if (numValid != validList.length)
 474:       {
 475:         trimmedList = new Window [numValid];
 476:         System.arraycopy (validList, 0, trimmedList, 0, numValid);
 477:       }
 478:     else
 479:       trimmedList = validList;
 480:       }
 481:     return trimmedList;
 482:   }
 483: 
 484:   /**
 485:    * Adds the specified listener to the list of <code>WindowListeners</code>
 486:    * that will receive events for this window.
 487:    *
 488:    * @param listener The <code>WindowListener</code> to add.
 489:    */
 490:   public synchronized void addWindowListener(WindowListener listener)
 491:   {
 492:     if (listener != null)
 493:       {
 494:         newEventsOnly = true;
 495:         windowListener = AWTEventMulticaster.add(windowListener, listener);
 496:       }
 497:   }
 498: 
 499:   /**
 500:    * Removes the specified listener from the list of
 501:    * <code>WindowListeners</code> that will receive events for this window.
 502:    *
 503:    * @param listener The <code>WindowListener</code> to remove.
 504:    */
 505:   public synchronized void removeWindowListener(WindowListener listener)
 506:   {
 507:     windowListener = AWTEventMulticaster.remove(windowListener, listener);
 508:   }
 509: 
 510:   /**
 511:    * Returns an array of all the window listeners registered on this window.
 512:    *
 513:    * @since 1.4
 514:    */
 515:   public synchronized WindowListener[] getWindowListeners()
 516:   {
 517:     return (WindowListener[])
 518:       AWTEventMulticaster.getListeners(windowListener,
 519:                                        WindowListener.class);
 520:   }
 521: 
 522:   /**
 523:    * Returns an array of all the window focus listeners registered on this
 524:    * window.
 525:    *
 526:    * @since 1.4
 527:    */
 528:   public synchronized WindowFocusListener[] getWindowFocusListeners()
 529:   {
 530:     return (WindowFocusListener[])
 531:       AWTEventMulticaster.getListeners(windowFocusListener,
 532:                                        WindowFocusListener.class);
 533:   }
 534:   
 535:   /**
 536:    * Returns an array of all the window state listeners registered on this
 537:    * window.
 538:    *
 539:    * @since 1.4
 540:    */
 541:   public synchronized WindowStateListener[] getWindowStateListeners()
 542:   {
 543:     return (WindowStateListener[])
 544:       AWTEventMulticaster.getListeners(windowStateListener,
 545:                                        WindowStateListener.class);
 546:   }
 547: 
 548:   /**
 549:    * Adds the specified listener to this window.
 550:    */
 551:   public void addWindowFocusListener (WindowFocusListener wfl)
 552:   {
 553:     if (wfl != null)
 554:       {
 555:         newEventsOnly = true;
 556:         windowFocusListener = AWTEventMulticaster.add (windowFocusListener,
 557:                                                        wfl);
 558:       }
 559:   }
 560:   
 561:   /**
 562:    * Adds the specified listener to this window.
 563:    *
 564:    * @since 1.4
 565:    */
 566:   public void addWindowStateListener (WindowStateListener wsl)
 567:   {
 568:     if (wsl != null)
 569:       {
 570:         newEventsOnly = true;
 571:         windowStateListener = AWTEventMulticaster.add (windowStateListener,
 572:                                                        wsl);  
 573:       }
 574:   }
 575:   
 576:   /**
 577:    * Removes the specified listener from this window.
 578:    */
 579:   public void removeWindowFocusListener (WindowFocusListener wfl)
 580:   {
 581:     windowFocusListener = AWTEventMulticaster.remove (windowFocusListener, wfl);
 582:   }
 583:   
 584:   /**
 585:    * Removes the specified listener from this window.
 586:    *
 587:    * @since 1.4
 588:    */
 589:   public void removeWindowStateListener (WindowStateListener wsl)
 590:   {
 591:     windowStateListener = AWTEventMulticaster.remove (windowStateListener, wsl);
 592:   }
 593: 
 594:   /**
 595:    * Returns an array of all the objects currently registered as FooListeners
 596:    * upon this Window. FooListeners are registered using the addFooListener
 597:    * method.
 598:    *
 599:    * @exception ClassCastException If listenerType doesn't specify a class or
 600:    * interface that implements java.util.EventListener.
 601:    *
 602:    * @since 1.3
 603:    */
 604:   public <T extends EventListener> T[] getListeners(Class<T> listenerType)
 605:   {
 606:     if (listenerType == WindowListener.class)
 607:       return (T[]) getWindowListeners();
 608:     return super.getListeners(listenerType);
 609:   }
 610: 
 611:   void dispatchEventImpl(AWTEvent e)
 612:   {
 613:     if (e.getID() == ComponentEvent.COMPONENT_RESIZED)
 614:       {
 615:         invalidate();
 616:         validate();
 617:       }
 618:     super.dispatchEventImpl(e);
 619:   }
 620: 
 621:   /**
 622:    * Processes the specified event for this window.  If the event is an
 623:    * instance of <code>WindowEvent</code>, then
 624:    * <code>processWindowEvent()</code> is called to process the event,
 625:    * otherwise the superclass version of this method is invoked.
 626:    *
 627:    * @param evt The event to process.
 628:    */
 629:   protected void processEvent(AWTEvent evt)
 630:   {
 631:     if (evt instanceof WindowEvent)
 632:       {
 633:         WindowEvent we = (WindowEvent) evt;
 634:         switch (evt.getID())
 635:           {
 636:           case WindowEvent.WINDOW_OPENED:
 637:           case WindowEvent.WINDOW_CLOSED:
 638:           case WindowEvent.WINDOW_CLOSING:
 639:           case WindowEvent.WINDOW_ICONIFIED:
 640:           case WindowEvent.WINDOW_DEICONIFIED:
 641:           case WindowEvent.WINDOW_ACTIVATED:
 642:           case WindowEvent.WINDOW_DEACTIVATED:
 643:             processWindowEvent(we);
 644:             break;
 645:           case WindowEvent.WINDOW_GAINED_FOCUS:
 646:           case WindowEvent.WINDOW_LOST_FOCUS:
 647:             processWindowFocusEvent(we);
 648:             break;
 649:           case WindowEvent.WINDOW_STATE_CHANGED:
 650:             processWindowStateEvent(we);
 651:             break;
 652:           }
 653:       }
 654:     else
 655:       super.processEvent(evt);
 656:   }
 657: 
 658:   /**
 659:    * Dispatches this event to any listeners that are listening for
 660:    * <code>WindowEvents</code> on this window.  This method only gets
 661:    * invoked if it is enabled via <code>enableEvents()</code> or if
 662:    * a listener has been added.
 663:    *
 664:    * @param evt The event to process.
 665:    */
 666:   protected void processWindowEvent(WindowEvent evt)
 667:   {
 668:     if (windowListener != null)
 669:       {
 670:         switch (evt.getID())
 671:           {
 672:           case WindowEvent.WINDOW_ACTIVATED:
 673:             windowListener.windowActivated(evt);
 674:             break;
 675:           case WindowEvent.WINDOW_CLOSED:
 676:             windowListener.windowClosed(evt);
 677:             break;
 678:           case WindowEvent.WINDOW_CLOSING:
 679:             windowListener.windowClosing(evt);
 680:             break;
 681:           case WindowEvent.WINDOW_DEACTIVATED:
 682:             windowListener.windowDeactivated(evt);
 683:             break;
 684:           case WindowEvent.WINDOW_DEICONIFIED:
 685:             windowListener.windowDeiconified(evt);
 686:             break;
 687:           case WindowEvent.WINDOW_ICONIFIED:
 688:             windowListener.windowIconified(evt);
 689:             break;
 690:           case WindowEvent.WINDOW_OPENED:
 691:             windowListener.windowOpened(evt);
 692:             break;
 693:           }
 694:       }
 695:   }
 696: 
 697:   /**
 698:    * Identifies if this window is active.  The active window is a Frame or
 699:    * Dialog that has focus or owns the active window.
 700:    *  
 701:    * @return true if active, else false.
 702:    * @since 1.4
 703:    */
 704:   public boolean isActive()
 705:   {
 706:     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
 707:     return manager.getActiveWindow() == this;
 708:   }
 709: 
 710:   /**
 711:    * Identifies if this window is focused.  A window is focused if it is the
 712:    * focus owner or it contains the focus owner.
 713:    * 
 714:    * @return true if focused, else false.
 715:    * @since 1.4
 716:    */
 717:   public boolean isFocused()
 718:   {
 719:     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
 720:     return manager.getFocusedWindow() == this;
 721:   }
 722:   
 723:   /**
 724:    * Returns the child window that has focus if this window is active.
 725:    * This method returns <code>null</code> if this window is not active
 726:    * or no children have focus.
 727:    *
 728:    * @return The component that has focus, or <code>null</code> if no
 729:    * component has focus.
 730:    */
 731:   public Component getFocusOwner ()
 732:   {
 733:     KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager ();
 734: 
 735:     Window activeWindow = manager.getActiveWindow ();
 736: 
 737:     // The currently-focused Component belongs to the active Window.
 738:     if (activeWindow == this)
 739:       return manager.getFocusOwner ();
 740:     else
 741:       return null;
 742:   }
 743: 
 744:   /**
 745:    * Returns the child component of this window that would receive
 746:    * focus if this window were to become focused.  If the window
 747:    * already has the top-level focus, then this method returns the
 748:    * same component as getFocusOwner.  If no child component has
 749:    * requested focus within the window, then the initial focus owner
 750:    * is returned.  If this is a non-focusable window, this method
 751:    * returns null.
 752:    *
 753:    * @return the child component of this window that most recently had
 754:    * the focus, or <code>null</code>
 755:    * @since 1.4
 756:    */
 757:   public Component getMostRecentFocusOwner ()
 758:   {
 759:     return windowFocusOwner;
 760:   }
 761: 
 762:   /**
 763:    * Set the focus owner for this window.  This method is used to
 764:    * remember which component was focused when this window lost
 765:    * top-level focus, so that when it regains top-level focus the same
 766:    * child component can be refocused.
 767:    *
 768:    * @param windowFocusOwner the component in this window that owns
 769:    * the focus.
 770:    */
 771:   void setFocusOwner (Component windowFocusOwner)
 772:   {
 773:     this.windowFocusOwner = windowFocusOwner;
 774:   }
 775: 
 776:   /**
 777:    * Post a Java 1.0 event to the event queue.
 778:    *
 779:    * @param e The event to post.
 780:    *
 781:    * @deprecated
 782:    */
 783:   public boolean postEvent(Event e)
 784:   {
 785:     return handleEvent (e);
 786:   }
 787: 
 788:   /**
 789:    * Tests whether or not this window is visible on the screen.
 790:    *
 791:    * In contrast to the normal behaviour of Container, which is that
 792:    * a container is showing if its parent is visible and showing, a Window
 793:    * is even showing, if its parent (i.e. an invisible Frame) is not showing.
 794:    *
 795:    * @return <code>true</code> if this window is visible, <code>false</code>
 796:    * otherwise.
 797:    */
 798:   public boolean isShowing()
 799:   {
 800:     return isVisible();
 801:   }
 802: 
 803:   public void setLocationRelativeTo(Component c)
 804:   {
 805:     int x = 0;
 806:     int y = 0;
 807:     
 808:     if (c == null || !c.isShowing())
 809:       {
 810:         GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
 811:         Point center = ge.getCenterPoint();
 812:         x = center.x - (width / 2);
 813:         y = center.y - (height / 2);
 814:       }
 815:     else
 816:       {
 817:         int cWidth = c.getWidth();
 818:         int cHeight = c.getHeight();
 819:         Dimension screenSize = getToolkit().getScreenSize();
 820: 
 821:         x = c.getLocationOnScreen().x;
 822:         y = c.getLocationOnScreen().y;
 823:         
 824:         // If bottom of component is cut off, window placed
 825:         // on the left or the right side of component
 826:         if ((y + cHeight) > screenSize.height)
 827:           {
 828:             // If the right side of the component is closer to the center
 829:             if ((screenSize.width / 2 - x) <= 0)
 830:               {
 831:                 if ((x - width) >= 0)
 832:                   x -= width;
 833:                 else
 834:                   x = 0;
 835:               }
 836:             else
 837:               {
 838:                 if ((x + cWidth + width) <= screenSize.width)
 839:                   x += cWidth;
 840:                 else
 841:                   x = screenSize.width - width;
 842:               }
 843: 
 844:             y = screenSize.height - height;
 845:           }
 846:         else if (cWidth > width || cHeight > height)
 847:           {
 848:             // If right side of component is cut off
 849:             if ((x + width) > screenSize.width)
 850:               x = screenSize.width - width;
 851:             // If left side of component is cut off
 852:             else if (x < 0)
 853:               x = 0;
 854:             else
 855:               x += (cWidth - width) / 2;
 856:             
 857:             y += (cHeight - height) / 2;
 858:           }
 859:         else
 860:           {
 861:             // If right side of component is cut off
 862:             if ((x + width) > screenSize.width)
 863:               x = screenSize.width - width;
 864:             // If left side of component is cut off
 865:             else if (x < 0 || (x - (width - cWidth) / 2) < 0)
 866:               x = 0;
 867:             else
 868:               x -= (width - cWidth) / 2;
 869: 
 870:             if ((y - (height - cHeight) / 2) > 0)
 871:               y -= (height - cHeight) / 2;
 872:             else
 873:               y = 0;
 874:           }
 875:       }
 876: 
 877:     setLocation(x, y);
 878:   }
 879: 
 880:   /**
 881:    * A BltBufferStrategy for windows.
 882:    */
 883:   private class WindowBltBufferStrategy extends BltBufferStrategy
 884:   {
 885:     /**
 886:      * Creates a block transfer strategy for this window.
 887:      *
 888:      * @param numBuffers the number of buffers in this strategy
 889:      * @param accelerated true if the buffer should be accelerated,
 890:      * false otherwise
 891:      */
 892:     WindowBltBufferStrategy(int numBuffers, boolean accelerated)
 893:     {
 894:       super(numBuffers,
 895:         new BufferCapabilities(new ImageCapabilities(accelerated),
 896:                    new ImageCapabilities(accelerated),
 897:                    BufferCapabilities.FlipContents.COPIED));
 898:     }
 899:   }
 900: 
 901:   /**
 902:    * A FlipBufferStrategy for windows.
 903:    */
 904:   private class WindowFlipBufferStrategy extends FlipBufferStrategy
 905:   {
 906:     /**
 907:      * Creates a flip buffer strategy for this window.
 908:      *
 909:      * @param numBuffers the number of buffers in this strategy
 910:      *
 911:      * @throws AWTException if the requested number of buffers is not
 912:      * supported
 913:      */
 914:     WindowFlipBufferStrategy(int numBuffers)
 915:       throws AWTException
 916:     {
 917:       super(numBuffers,
 918:         new BufferCapabilities(new ImageCapabilities(true),
 919:                    new ImageCapabilities(true),
 920:                    BufferCapabilities.FlipContents.COPIED));
 921:     }
 922:   }
 923: 
 924:   /**
 925:    * Creates a buffering strategy that manages how this window is
 926:    * repainted.  This method attempts to create the optimum strategy
 927:    * based on the desired number of buffers.  Hardware or software
 928:    * acceleration may be used.
 929:    *
 930:    * createBufferStrategy attempts different levels of optimization,
 931:    * but guarantees that some strategy with the requested number of
 932:    * buffers will be created even if it is not optimal.  First it
 933:    * attempts to create a page flipping strategy, then an accelerated
 934:    * blitting strategy, then an unaccelerated blitting strategy.
 935:    *
 936:    * Calling this method causes any existing buffer strategy to be
 937:    * destroyed.
 938:    *
 939:    * @param numBuffers the number of buffers in this strategy
 940:    *
 941:    * @throws IllegalArgumentException if requested number of buffers
 942:    * is less than one
 943:    * @throws IllegalStateException if this window is not displayable
 944:    *
 945:    * @since 1.4
 946:    */
 947:   public void createBufferStrategy(int numBuffers)
 948:   {
 949:     if (numBuffers < 1)
 950:       throw new IllegalArgumentException("Window.createBufferStrategy: number"
 951:                      + " of buffers is less than one");
 952: 
 953:     if (!isDisplayable())
 954:       throw new IllegalStateException("Window.createBufferStrategy: window is"
 955:                       + " not displayable");
 956: 
 957:     BufferStrategy newStrategy = null;
 958: 
 959:     // try a flipping strategy
 960:     try
 961:       {
 962:     newStrategy = new WindowFlipBufferStrategy(numBuffers);
 963:       }
 964:     catch (AWTException e)
 965:       {
 966:       }
 967: 
 968:     // fall back to an accelerated blitting strategy
 969:     if (newStrategy == null)
 970:       newStrategy = new WindowBltBufferStrategy(numBuffers, true);
 971: 
 972:     bufferStrategy = newStrategy;
 973:   }
 974: 
 975:   /**
 976:    * Creates a buffering strategy that manages how this window is
 977:    * repainted.  This method attempts to create a strategy based on
 978:    * the specified capabilities and throws an exception if the
 979:    * requested strategy is not supported.
 980:    *
 981:    * Calling this method causes any existing buffer strategy to be
 982:    * destroyed.
 983:    *
 984:    * @param numBuffers the number of buffers in this strategy
 985:    * @param caps the requested buffering capabilities
 986:    *
 987:    * @throws AWTException if the requested capabilities are not
 988:    * supported
 989:    * @throws IllegalArgumentException if requested number of buffers
 990:    * is less than one or if caps is null
 991:    *
 992:    * @since 1.4
 993:    */
 994:   public void createBufferStrategy(int numBuffers, BufferCapabilities caps)
 995:     throws AWTException
 996:   {
 997:     if (numBuffers < 1)
 998:       throw new IllegalArgumentException("Window.createBufferStrategy: number"
 999:                      + " of buffers is less than one");
1000: 
1001:     if (caps == null)
1002:       throw new IllegalArgumentException("Window.createBufferStrategy:"
1003:                      + " capabilities object is null");
1004: 
1005:     // a flipping strategy was requested
1006:     if (caps.isPageFlipping())
1007:       bufferStrategy = new WindowFlipBufferStrategy(numBuffers);
1008:     else
1009:       bufferStrategy = new WindowBltBufferStrategy(numBuffers, true);
1010:   }
1011: 
1012:   /**
1013:    * Returns the buffer strategy used by the window.
1014:    *
1015:    * @return the buffer strategy.
1016:    * @since 1.4
1017:    */
1018:   public BufferStrategy getBufferStrategy()
1019:   {
1020:     return bufferStrategy;
1021:   }
1022: 
1023:   /**
1024:    * @since 1.2
1025:    *
1026:    * @deprecated replaced by Component.applyComponentOrientation.
1027:    */
1028:   public void applyResourceBundle(ResourceBundle rb)
1029:   {
1030:     applyComponentOrientation(ComponentOrientation.getOrientation(rb));
1031:   }
1032: 
1033:   /**
1034:    * @since 1.2
1035:    *
1036:    * @deprecated
1037:    */
1038:   public void applyResourceBundle(String rbName)
1039:   {
1040:     ResourceBundle rb = ResourceBundle.getBundle(rbName, Locale.getDefault(),
1041:       ClassLoader.getSystemClassLoader());
1042:     if (rb != null)
1043:       applyResourceBundle(rb);    
1044:   }
1045: 
1046:   /**
1047:    * Gets the AccessibleContext associated with this <code>Window</code>.
1048:    * The context is created, if necessary.
1049:    *
1050:    * @return the associated context
1051:    */
1052:   public AccessibleContext getAccessibleContext()
1053:   {
1054:     /* Create the context if this is the first request */
1055:     if (accessibleContext == null)
1056:       accessibleContext = new AccessibleAWTWindow();
1057:     return accessibleContext;
1058:   }
1059: 
1060:   /** 
1061:    * Get graphics configuration.  The implementation for Window will
1062:    * not ask any parent containers, since Window is a toplevel
1063:    * window and not actually embedded in the parent component.
1064:    */
1065:   public GraphicsConfiguration getGraphicsConfiguration()
1066:   {
1067:     GraphicsConfiguration conf = graphicsConfig;
1068:     if (conf == null)
1069:       {
1070:         conf = GraphicsEnvironment.getLocalGraphicsEnvironment()
1071:         .getDefaultScreenDevice().getDefaultConfiguration();
1072:         graphicsConfig = conf;
1073:       }
1074:     return conf;
1075:   }
1076: 
1077:   protected void processWindowFocusEvent(WindowEvent event)
1078:   {
1079:     if (windowFocusListener != null)
1080:       {
1081:         switch (event.getID ())
1082:           {
1083:           case WindowEvent.WINDOW_GAINED_FOCUS:
1084:             windowFocusListener.windowGainedFocus (event);
1085:             break;
1086:             
1087:           case WindowEvent.WINDOW_LOST_FOCUS:
1088:             windowFocusListener.windowLostFocus (event);
1089:             break;
1090:             
1091:           default:
1092:             break;
1093:           }
1094:       }
1095:   }
1096:   
1097:   /**
1098:    * @since 1.4
1099:    */
1100:   protected void processWindowStateEvent(WindowEvent event)
1101:   {
1102:     if (windowStateListener != null
1103:         && event.getID () == WindowEvent.WINDOW_STATE_CHANGED)
1104:       windowStateListener.windowStateChanged (event);
1105:   }
1106: 
1107:   /**
1108:    * Returns whether this <code>Window</code> can get the focus or not.
1109:    *
1110:    * @since 1.4
1111:    */
1112:   public final boolean isFocusableWindow ()
1113:   {
1114:     if (getFocusableWindowState () == false)
1115:       return false;
1116: 
1117:     if (this instanceof Dialog
1118:         || this instanceof Frame)
1119:       return true;
1120: 
1121:     // FIXME: Implement more possible cases for returning true.
1122: 
1123:     return false;
1124:   }
1125:   
1126:   /**
1127:    * Returns the value of the focusableWindowState property.
1128:    * 
1129:    * @since 1.4
1130:    */
1131:   public boolean getFocusableWindowState ()
1132:   {
1133:     return focusableWindowState;
1134:   }
1135: 
1136:   /**
1137:    * Sets the value of the focusableWindowState property.
1138:    * 
1139:    * @since 1.4
1140:    */
1141:   public void setFocusableWindowState (boolean focusableWindowState)
1142:   {
1143:     this.focusableWindowState = focusableWindowState;
1144:   }
1145:   
1146:   /**
1147:    * Check whether this Container is a focus cycle root.
1148:    * Returns always <code>true</code> as Windows are the 
1149:    * root of the focus cycle.
1150:    *
1151:    * @return Always <code>true</code>.
1152:    *
1153:    * @since 1.4
1154:    */
1155:   public final boolean isFocusCycleRoot()
1156:   {
1157:     return true;
1158:   }
1159: 
1160:   /**
1161:    * Set whether or not this Container is the root of a focus
1162:    * traversal cycle. Windows are the root of the focus cycle
1163:    * and therefore this method does nothing.
1164:    * 
1165:    * @param focusCycleRoot ignored.
1166:    *
1167:    * @since 1.4
1168:    */
1169:   public final void setFocusCycleRoot(boolean focusCycleRoot)
1170:   {
1171:     // calls to the method are ignored
1172:   }
1173: 
1174:   /**
1175:    * Returns the root container that owns the focus cycle where this
1176:    * component resides. Windows have no ancestors and this method
1177:    * returns always <code>null</code>.
1178:    *
1179:    * @return Always <code>null</code>.
1180:    * @since 1.4
1181:    */
1182:   public final Container getFocusCycleRootAncestor()
1183:   {
1184:     return null;
1185:   }
1186: 
1187:   /**
1188:    * Returns whether the Windows is an always-on-top window,
1189:    * meaning whether the window can be obscured by other windows or not.
1190:    *
1191:    * @return <code>true</code> if the windows is always-on-top,
1192:    * <code>false</code> otherwise.
1193:    * @since 1.5
1194:    */
1195:   public final boolean isAlwaysOnTop()
1196:   {
1197:     return alwaysOnTop;
1198:   }
1199: 
1200:   /**
1201:    * Sets the always-on-top state of this window (if supported).
1202:    *
1203:    * Setting a window to always-on-top means it will not be obscured
1204:    * by any other windows (with the exception of other always-on-top 
1205:    * windows). Not all platforms may support this.
1206:    *
1207:    * If an window's always-on-top status is changed to false, the window
1208:    * will remain at the front but not be anchored there.
1209:    *
1210:    * Calling toBack() on an always-on-top window will change its
1211:    * always-on-top status to false.
1212:    *
1213:    * @since 1.5
1214:    */
1215:   public final void setAlwaysOnTop(boolean alwaysOnTop)
1216:   {
1217:     SecurityManager sm = System.getSecurityManager();
1218:     if (sm != null)
1219:       sm.checkPermission( new AWTPermission("setWindowAlwaysOnTop") );
1220: 
1221:     if( this.alwaysOnTop == alwaysOnTop )
1222:       return;
1223:     
1224:     if( alwaysOnTop )
1225:       toFront();
1226: 
1227:     firePropertyChange("alwaysOnTop", this.alwaysOnTop, alwaysOnTop );
1228:     this.alwaysOnTop = alwaysOnTop;
1229: 
1230:     if (peer != null) 
1231:       ( (WindowPeer) peer).updateAlwaysOnTop();
1232:     else
1233:       System.out.println("Null peer?!");
1234:   }
1235: 
1236:   /**
1237:    * Generate a unique name for this window.
1238:    *
1239:    * @return A unique name for this window.
1240:    */
1241:   String generateName()
1242:   {
1243:     return "win" + getUniqueLong();
1244:   }
1245: 
1246:   /**
1247:    * Overridden to handle WindowEvents.
1248:    *
1249:    * @return <code>true</code> when the specified event type is enabled,
1250:    *         <code>false</code> otherwise
1251:    */
1252:   boolean eventTypeEnabled(int type)
1253:   {
1254:     boolean enabled = false;
1255:     switch (type)
1256:       {
1257:         case WindowEvent.WINDOW_OPENED:
1258:         case WindowEvent.WINDOW_CLOSED:
1259:         case WindowEvent.WINDOW_CLOSING:
1260:         case WindowEvent.WINDOW_ICONIFIED:
1261:         case WindowEvent.WINDOW_DEICONIFIED:
1262:         case WindowEvent.WINDOW_ACTIVATED:
1263:         case WindowEvent.WINDOW_DEACTIVATED:
1264:           enabled = ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0)
1265:                     || windowListener != null;
1266:           break;
1267:         case WindowEvent.WINDOW_GAINED_FOCUS:
1268:         case WindowEvent.WINDOW_LOST_FOCUS:
1269:           enabled = ((eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0)
1270:                     || windowFocusListener != null;
1271:           break;
1272:         case WindowEvent.WINDOW_STATE_CHANGED:
1273:           enabled = ((eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0)
1274:                     || windowStateListener != null;
1275:           break;
1276:         default:
1277:           enabled = super.eventTypeEnabled(type);
1278:       }
1279:     return enabled;
1280:   }
1281: 
1282:   private static synchronized long getUniqueLong()
1283:   {
1284:     return next_window_number++;
1285:   }
1286: }