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