Source for java.awt.Window

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