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