Source for java.awt.Window

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