Save This Page
Home » openjdk-7 » java » awt » [javadoc | source]
    1   /*
    2    * Copyright 1995-2008 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   package java.awt;
   26   
   27   import java.awt.event;
   28   import java.awt.im.InputContext;
   29   import java.awt.image.BufferStrategy;
   30   import java.awt.peer.ComponentPeer;
   31   import java.awt.peer.WindowPeer;
   32   import java.beans.PropertyChangeListener;
   33   import java.io.IOException;
   34   import java.io.ObjectInputStream;
   35   import java.io.ObjectOutputStream;
   36   import java.io.OptionalDataException;
   37   import java.io.Serializable;
   38   import java.lang.ref.WeakReference;
   39   import java.lang.reflect.InvocationTargetException;
   40   import java.security.AccessController;
   41   import java.util.ArrayList;
   42   import java.util.Arrays;
   43   import java.util.EventListener;
   44   import java.util.Locale;
   45   import java.util.ResourceBundle;
   46   import java.util.Set;
   47   import java.util.Vector;
   48   import java.util.logging.Level;
   49   import java.util.logging.Logger;
   50   import java.util.concurrent.atomic.AtomicBoolean;
   51   import javax.accessibility;
   52   import sun.awt.AppContext;
   53   import sun.awt.CausedFocusEvent;
   54   import sun.awt.SunToolkit;
   55   import sun.awt.util.IdentityArrayList;
   56   import sun.java2d.pipe.Region;
   57   import sun.security.action.GetPropertyAction;
   58   import sun.security.util.SecurityConstants;
   59   
   60   /**
   61    * A <code>Window</code> object is a top-level window with no borders and no
   62    * menubar.
   63    * The default layout for a window is <code>BorderLayout</code>.
   64    * <p>
   65    * A window must have either a frame, dialog, or another window defined as its
   66    * owner when it's constructed.
   67    * <p>
   68    * In a multi-screen environment, you can create a <code>Window</code>
   69    * on a different screen device by constructing the <code>Window</code>
   70    * with {@link #Window(Window, GraphicsConfiguration)}.  The
   71    * <code>GraphicsConfiguration</code> object is one of the
   72    * <code>GraphicsConfiguration</code> objects of the target screen device.
   73    * <p>
   74    * In a virtual device multi-screen environment in which the desktop
   75    * area could span multiple physical screen devices, the bounds of all
   76    * configurations are relative to the virtual device coordinate system.
   77    * The origin of the virtual-coordinate system is at the upper left-hand
   78    * corner of the primary physical screen.  Depending on the location of
   79    * the primary screen in the virtual device, negative coordinates are
   80    * possible, as shown in the following figure.
   81    * <p>
   82    * <img src="doc-files/MultiScreen.gif"
   83    * alt="Diagram shows virtual device containing 4 physical screens. Primary physical screen shows coords (0,0), other screen shows (-80,-100)."
   84    * ALIGN=center HSPACE=10 VSPACE=7>
   85    * <p>
   86    * In such an environment, when calling <code>setLocation</code>,
   87    * you must pass a virtual coordinate to this method.  Similarly,
   88    * calling <code>getLocationOnScreen</code> on a <code>Window</code> returns
   89    * virtual device coordinates.  Call the <code>getBounds</code> method
   90    * of a <code>GraphicsConfiguration</code> to find its origin in the virtual
   91    * coordinate system.
   92    * <p>
   93    * The following code sets the location of a <code>Window</code>
   94    * at (10, 10) relative to the origin of the physical screen
   95    * of the corresponding <code>GraphicsConfiguration</code>.  If the
   96    * bounds of the <code>GraphicsConfiguration</code> is not taken
   97    * into account, the <code>Window</code> location would be set
   98    * at (10, 10) relative to the virtual-coordinate system and would appear
   99    * on the primary physical screen, which might be different from the
  100    * physical screen of the specified <code>GraphicsConfiguration</code>.
  101    *
  102    * <pre>
  103    *      Window w = new Window(Window owner, GraphicsConfiguration gc);
  104    *      Rectangle bounds = gc.getBounds();
  105    *      w.setLocation(10 + bounds.x, 10 + bounds.y);
  106    * </pre>
  107    *
  108    * <p>
  109    * Note: the location and size of top-level windows (including
  110    * <code>Window</code>s, <code>Frame</code>s, and <code>Dialog</code>s)
  111    * are under the control of the desktop's window management system.
  112    * Calls to <code>setLocation</code>, <code>setSize</code>, and
  113    * <code>setBounds</code> are requests (not directives) which are
  114    * forwarded to the window management system.  Every effort will be
  115    * made to honor such requests.  However, in some cases the window
  116    * management system may ignore such requests, or modify the requested
  117    * geometry in order to place and size the <code>Window</code> in a way
  118    * that more closely matches the desktop settings.
  119    * <p>
  120    * Due to the asynchronous nature of native event handling, the results
  121    * returned by <code>getBounds</code>, <code>getLocation</code>,
  122    * <code>getLocationOnScreen</code>, and <code>getSize</code> might not
  123    * reflect the actual geometry of the Window on screen until the last
  124    * request has been processed.  During the processing of subsequent
  125    * requests these values might change accordingly while the window
  126    * management system fulfills the requests.
  127    * <p>
  128    * An application may set the size and location of an invisible
  129    * {@code Window} arbitrarily, but the window management system may
  130    * subsequently change its size and/or location when the
  131    * {@code Window} is made visible. One or more {@code ComponentEvent}s
  132    * will be generated to indicate the new geometry.
  133    * <p>
  134    * Windows are capable of generating the following WindowEvents:
  135    * WindowOpened, WindowClosed, WindowGainedFocus, WindowLostFocus.
  136    *
  137    * @author      Sami Shaio
  138    * @author      Arthur van Hoff
  139    * @see WindowEvent
  140    * @see #addWindowListener
  141    * @see java.awt.BorderLayout
  142    * @since       JDK1.0
  143    */
  144   public class Window extends Container implements Accessible {
  145   
  146       /**
  147        * This represents the warning message that is
  148        * to be displayed in a non secure window. ie :
  149        * a window that has a security manager installed for
  150        * which calling SecurityManager.checkTopLevelWindow()
  151        * is false.  This message can be displayed anywhere in
  152        * the window.
  153        *
  154        * @serial
  155        * @see #getWarningString
  156        */
  157       String      warningString;
  158   
  159       /**
  160        * {@code icons} is the graphical way we can
  161        * represent the frames and dialogs.
  162        * {@code Window} can't display icon but it's
  163        * being inherited by owned {@code Dialog}s.
  164        *
  165        * @serial
  166        * @see #getIconImages
  167        * @see #setIconImages(List<? extends Image>)
  168        */
  169       transient java.util.List<Image> icons;
  170   
  171       /**
  172        * Holds the reference to the component which last had focus in this window
  173        * before it lost focus.
  174        */
  175       private transient Component temporaryLostComponent;
  176   
  177       static boolean systemSyncLWRequests = false;
  178       boolean     syncLWRequests = false;
  179       transient boolean beforeFirstShow = true;
  180   
  181       static final int OPENED = 0x01;
  182   
  183       /**
  184        * An Integer value representing the Window State.
  185        *
  186        * @serial
  187        * @since 1.2
  188        * @see #show
  189        */
  190       int state;
  191   
  192       /**
  193        * A boolean value representing Window always-on-top state
  194        * @since 1.5
  195        * @serial
  196        * @see #setAlwaysOnTop
  197        * @see #isAlwaysOnTop
  198        */
  199       private boolean alwaysOnTop;
  200   
  201       /**
  202        * Contains all the windows that have a peer object associated,
  203        * i. e. between addNotify() and removeNotify() calls. The list
  204        * of all Window instances can be obtained from AppContext object.
  205        *
  206        * @since 1.6
  207        */
  208       private static final IdentityArrayList<Window> allWindows = new IdentityArrayList<Window>();
  209   
  210       /**
  211        * A vector containing all the windows this
  212        * window currently owns.
  213        * @since 1.2
  214        * @see #getOwnedWindows
  215        */
  216       transient Vector<WeakReference<Window>> ownedWindowList =
  217                                               new Vector<WeakReference<Window>>();
  218   
  219       /*
  220        * We insert a weak reference into the Vector of all Windows in AppContext
  221        * instead of 'this' so that garbage collection can still take place
  222        * correctly.
  223        */
  224       private transient WeakReference<Window> weakThis;
  225   
  226       transient boolean showWithParent;
  227   
  228       /**
  229        * Contains the modal dialog that blocks this window, or null
  230        * if the window is unblocked.
  231        *
  232        * @since 1.6
  233        */
  234       transient Dialog modalBlocker;
  235   
  236       /**
  237        * @serial
  238        *
  239        * @see java.awt.Dialog.ModalExclusionType
  240        * @see #getModalExclusionType
  241        * @see #setModalExclusionType
  242        *
  243        * @since 1.6
  244        */
  245       Dialog.ModalExclusionType modalExclusionType;
  246   
  247       transient WindowListener windowListener;
  248       transient WindowStateListener windowStateListener;
  249       transient WindowFocusListener windowFocusListener;
  250   
  251       transient InputContext inputContext;
  252       private transient Object inputContextLock = new Object();
  253   
  254       /**
  255        * Unused. Maintained for serialization backward-compatibility.
  256        *
  257        * @serial
  258        * @since 1.2
  259        */
  260       private FocusManager focusMgr;
  261   
  262       /**
  263        * Indicates whether this Window can become the focused Window.
  264        *
  265        * @serial
  266        * @see #getFocusableWindowState
  267        * @see #setFocusableWindowState
  268        * @since 1.4
  269        */
  270       private boolean focusableWindowState = true;
  271   
  272       /**
  273        * Indicates whether this window should receive focus on
  274        * subsequently being shown (with a call to {@code setVisible(true)}), or
  275        * being moved to the front (with a call to {@code toFront()}).
  276        *
  277        * @serial
  278        * @see #setAutoRequestFocus
  279        * @see #isAutoRequestFocus
  280        * @since 1.7
  281        */
  282       private volatile boolean autoRequestFocus = true;
  283   
  284       /*
  285        * Indicates that this window is being shown. This flag is set to true at
  286        * the beginning of show() and to false at the end of show().
  287        *
  288        * @see #show()
  289        * @see Dialog#shouldBlock
  290        */
  291       transient boolean isInShow = false;
  292   
  293       private static final String base = "win";
  294       private static int nameCounter = 0;
  295   
  296       /*
  297        * JDK 1.1 serialVersionUID
  298        */
  299       private static final long serialVersionUID = 4497834738069338734L;
  300   
  301       private static final Logger log = Logger.getLogger("java.awt.Window");
  302   
  303       private static final boolean locationByPlatformProp;
  304   
  305       transient boolean isTrayIconWindow = false;
  306   
  307       static {
  308           /* ensure that the necessary native libraries are loaded */
  309           Toolkit.loadLibraries();
  310           if (!GraphicsEnvironment.isHeadless()) {
  311               initIDs();
  312           }
  313   
  314           String s = (String) java.security.AccessController.doPrivileged(
  315               new GetPropertyAction("java.awt.syncLWRequests"));
  316           systemSyncLWRequests = (s != null && s.equals("true"));
  317           s = (String) java.security.AccessController.doPrivileged(
  318               new GetPropertyAction("java.awt.Window.locationByPlatform"));
  319           locationByPlatformProp = (s != null && s.equals("true"));
  320       }
  321   
  322       /**
  323        * Initialize JNI field and method IDs for fields that may be
  324          accessed from C.
  325        */
  326       private static native void initIDs();
  327   
  328       /**
  329        * Constructs a new, initially invisible window in default size with the
  330        * specified <code>GraphicsConfiguration</code>.
  331        * <p>
  332        * If there is a security manager, this method first calls
  333        * the security manager's <code>checkTopLevelWindow</code>
  334        * method with <code>this</code>
  335        * as its argument to determine whether or not the window
  336        * must be displayed with a warning banner.
  337        *
  338        * @param gc the <code>GraphicsConfiguration</code> of the target screen
  339        *     device. If <code>gc</code> is <code>null</code>, the system default
  340        *     <code>GraphicsConfiguration</code> is assumed
  341        * @exception IllegalArgumentException if <code>gc</code>
  342        *    is not from a screen device
  343        * @exception HeadlessException when
  344        *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
  345        *
  346        * @see java.awt.GraphicsEnvironment#isHeadless
  347        * @see java.lang.SecurityManager#checkTopLevelWindow
  348        */
  349       Window(GraphicsConfiguration gc) {
  350           init(gc);
  351       }
  352   
  353       transient Object anchor = new Object();
  354       static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
  355           final WeakReference<Window> owner;
  356           final WeakReference weakThis;
  357           final WeakReference<AppContext> context;
  358           WindowDisposerRecord(AppContext context, Window victim) {
  359               owner = new WeakReference<Window>(victim.getOwner());
  360               weakThis = victim.weakThis;
  361               this.context = new WeakReference<AppContext>(context);
  362           }
  363           public void dispose() {
  364               Window parent = owner.get();
  365               if (parent != null) {
  366                   parent.removeOwnedWindow(weakThis);
  367               }
  368               AppContext ac = context.get();
  369               if (null != ac) {
  370                   Window.removeFromWindowList(ac, weakThis);
  371               }
  372           }
  373       }
  374   
  375       private void init(GraphicsConfiguration gc) {
  376           GraphicsEnvironment.checkHeadless();
  377   
  378           syncLWRequests = systemSyncLWRequests;
  379   
  380           weakThis = new WeakReference<Window>(this);
  381           addToWindowList();
  382   
  383           setWarningString();
  384           this.cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  385           this.visible = false;
  386           if (gc == null) {
  387               this.graphicsConfig =
  388                   GraphicsEnvironment.getLocalGraphicsEnvironment().
  389                getDefaultScreenDevice().getDefaultConfiguration();
  390           } else {
  391               this.graphicsConfig = gc;
  392           }
  393           if (graphicsConfig.getDevice().getType() !=
  394               GraphicsDevice.TYPE_RASTER_SCREEN) {
  395               throw new IllegalArgumentException("not a screen device");
  396           }
  397           setLayout(new BorderLayout());
  398   
  399           /* offset the initial location with the original of the screen */
  400           /* and any insets                                              */
  401           Rectangle screenBounds = graphicsConfig.getBounds();
  402           Insets screenInsets = getToolkit().getScreenInsets(graphicsConfig);
  403           int x = getX() + screenBounds.x + screenInsets.left;
  404           int y = getY() + screenBounds.y + screenInsets.top;
  405           if (x != this.x || y != this.y) {
  406               setLocation(x, y);
  407               /* reset after setLocation */
  408               setLocationByPlatform(locationByPlatformProp);
  409           }
  410   
  411           modalExclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
  412   
  413           sun.java2d.Disposer.addRecord(anchor, new WindowDisposerRecord(appContext, this));
  414       }
  415   
  416       /**
  417        * Constructs a new, initially invisible window in the default size.
  418        *
  419        * <p>First, if there is a security manager, its
  420        * <code>checkTopLevelWindow</code>
  421        * method is called with <code>this</code>
  422        * as its argument
  423        * to see if it's ok to display the window without a warning banner.
  424        * If the default implementation of <code>checkTopLevelWindow</code>
  425        * is used (that is, that method is not overriden), then this results in
  426        * a call to the security manager's <code>checkPermission</code> method
  427        * with an <code>AWTPermission("showWindowWithoutWarningBanner")</code>
  428        * permission. It that method raises a SecurityException,
  429        * <code>checkTopLevelWindow</code> returns false, otherwise it
  430        * returns true. If it returns false, a warning banner is created.
  431        *
  432        * @exception HeadlessException when
  433        *     <code>GraphicsEnvironment.isHeadless()</code> returns <code>true</code>
  434        *
  435        * @see java.awt.GraphicsEnvironment#isHeadless
  436        * @see java.lang.SecurityManager#checkTopLevelWindow
  437        */
  438       Window() throws HeadlessException {
  439           GraphicsEnvironment.checkHeadless();
  440           init((GraphicsConfiguration)null);
  441       }
  442   
  443       /**
  444        * Constructs a new, initially invisible window with the specified
  445        * <code>Frame</code> as its owner. The window will not be focusable
  446        * unless its owner is showing on the screen.
  447        * <p>
  448        * If there is a security manager, this method first calls
  449        * the security manager's <code>checkTopLevelWindow</code>
  450        * method with <code>this</code>
  451        * as its argument to determine whether or not the window
  452        * must be displayed with a warning banner.
  453        *
  454        * @param owner the <code>Frame</code> to act as owner or <code>null</code>
  455        *    if this window has no owner
  456        * @exception IllegalArgumentException if the <code>owner</code>'s
  457        *    <code>GraphicsConfiguration</code> is not from a screen device
  458        * @exception HeadlessException when
  459        *    <code>GraphicsEnvironment.isHeadless</code> returns <code>true</code>
  460        *
  461        * @see java.awt.GraphicsEnvironment#isHeadless
  462        * @see java.lang.SecurityManager#checkTopLevelWindow
  463        * @see #isShowing
  464        */
  465       public Window(Frame owner) {
  466           this(owner == null ? (GraphicsConfiguration)null :
  467               owner.getGraphicsConfiguration());
  468           ownedInit(owner);
  469       }
  470   
  471       /**
  472        * Constructs a new, initially invisible window with the specified
  473        * <code>Window</code> as its owner. This window will not be focusable
  474        * unless its nearest owning <code>Frame</code> or <code>Dialog</code>
  475        * is showing on the screen.
  476        * <p>
  477        * If there is a security manager, this method first calls
  478        * the security manager's <code>checkTopLevelWindow</code>
  479        * method with <code>this</code>
  480        * as its argument to determine whether or not the window
  481        * must be displayed with a warning banner.
  482        *
  483        * @param owner the <code>Window</code> to act as owner or
  484        *     <code>null</code> if this window has no owner
  485        * @exception IllegalArgumentException if the <code>owner</code>'s
  486        *     <code>GraphicsConfiguration</code> is not from a screen device
  487        * @exception HeadlessException when
  488        *     <code>GraphicsEnvironment.isHeadless()</code> returns
  489        *     <code>true</code>
  490        *
  491        * @see       java.awt.GraphicsEnvironment#isHeadless
  492        * @see       java.lang.SecurityManager#checkTopLevelWindow
  493        * @see       #isShowing
  494        *
  495        * @since     1.2
  496        */
  497       public Window(Window owner) {
  498           this(owner == null ? (GraphicsConfiguration)null :
  499               owner.getGraphicsConfiguration());
  500           ownedInit(owner);
  501       }
  502   
  503       /**
  504        * Constructs a new, initially invisible window with the specified owner
  505        * <code>Window</code> and a <code>GraphicsConfiguration</code>
  506        * of a screen device. The Window will not be focusable unless
  507        * its nearest owning <code>Frame</code> or <code>Dialog</code>
  508        * is showing on the screen.
  509        * <p>
  510        * If there is a security manager, this method first calls
  511        * the security manager's <code>checkTopLevelWindow</code>
  512        * method with <code>this</code>
  513        * as its argument to determine whether or not the window
  514        * must be displayed with a warning banner.
  515        *
  516        * @param owner the window to act as owner or <code>null</code>
  517        *     if this window has no owner
  518        * @param gc the <code>GraphicsConfiguration</code> of the target
  519        *     screen device; if <code>gc</code> is <code>null</code>,
  520        *     the system default <code>GraphicsConfiguration</code> is assumed
  521        * @exception IllegalArgumentException if <code>gc</code>
  522        *     is not from a screen device
  523        * @exception HeadlessException when
  524        *     <code>GraphicsEnvironment.isHeadless()</code> returns
  525        *     <code>true</code>
  526        *
  527        * @see       java.awt.GraphicsEnvironment#isHeadless
  528        * @see       java.lang.SecurityManager#checkTopLevelWindow
  529        * @see       GraphicsConfiguration#getBounds
  530        * @see       #isShowing
  531        * @since     1.3
  532        */
  533       public Window(Window owner, GraphicsConfiguration gc) {
  534           this(gc);
  535           ownedInit(owner);
  536       }
  537   
  538       private void ownedInit(Window owner) {
  539           this.parent = owner;
  540           if (owner != null) {
  541               owner.addOwnedWindow(weakThis);
  542           }
  543       }
  544   
  545       /**
  546        * Construct a name for this component.  Called by getName() when the
  547        * name is null.
  548        */
  549       String constructComponentName() {
  550           synchronized (Window.class) {
  551               return base + nameCounter++;
  552           }
  553       }
  554   
  555       /**
  556        * Returns the sequence of images to be displayed as the icon for this window.
  557        * <p>
  558        * This method returns a copy of the internally stored list, so all operations
  559        * on the returned object will not affect the window's behavior.
  560        *
  561        * @return    the copy of icon images' list for this window, or
  562        *            empty list if this window doesn't have icon images.
  563        * @see       #setIconImages
  564        * @see       #setIconImage(Image)
  565        * @since     1.6
  566        */
  567       public java.util.List<Image> getIconImages() {
  568           java.util.List<Image> icons = this.icons;
  569           if (icons == null || icons.size() == 0) {
  570               return new ArrayList<Image>();
  571           }
  572           return new ArrayList<Image>(icons);
  573       }
  574   
  575       /**
  576        * Sets the sequence of images to be displayed as the icon
  577        * for this window. Subsequent calls to {@code getIconImages} will
  578        * always return a copy of the {@code icons} list.
  579        * <p>
  580        * Depending on the platform capabilities one or several images
  581        * of different dimensions will be used as the window's icon.
  582        * <p>
  583        * The {@code icons} list is scanned for the images of most
  584        * appropriate dimensions from the beginning. If the list contains
  585        * several images of the same size, the first will be used.
  586        * <p>
  587        * Ownerless windows with no icon specified use platfrom-default icon.
  588        * The icon of an owned window may be inherited from the owner
  589        * unless explicitly overridden.
  590        * Setting the icon to {@code null} or empty list restores
  591        * the default behavior.
  592        * <p>
  593        * Note : Native windowing systems may use different images of differing
  594        * dimensions to represent a window, depending on the context (e.g.
  595        * window decoration, window list, taskbar, etc.). They could also use
  596        * just a single image for all contexts or no image at all.
  597        *
  598        * @param     icons the list of icon images to be displayed.
  599        * @see       #getIconImages()
  600        * @see       #setIconImage(Image)
  601        * @since     1.6
  602        */
  603       public synchronized void setIconImages(java.util.List<? extends Image> icons) {
  604           this.icons = (icons == null) ? new ArrayList<Image>() :
  605               new ArrayList<Image>(icons);
  606           WindowPeer peer = (WindowPeer)this.peer;
  607           if (peer != null) {
  608               peer.updateIconImages();
  609           }
  610           // Always send a property change event
  611           firePropertyChange("iconImage", null, null);
  612       }
  613   
  614       /**
  615        * Sets the image to be displayed as the icon for this window.
  616        * <p>
  617        * This method can be used instead of {@link #setIconImages setIconImages()}
  618        * to specify a single image as a window's icon.
  619        * <p>
  620        * The following statement:
  621        * <pre>
  622        *     setIconImage(image);
  623        * </pre>
  624        * is equivalent to:
  625        * <pre>
  626        *     ArrayList&lt;Image&gt; imageList = new ArrayList&lt;Image&gt;();
  627        *     imageList.add(image);
  628        *     setIconImages(imageList);
  629        * </pre>
  630        * <p>
  631        * Note : Native windowing systems may use different images of differing
  632        * dimensions to represent a window, depending on the context (e.g.
  633        * window decoration, window list, taskbar, etc.). They could also use
  634        * just a single image for all contexts or no image at all.
  635        *
  636        * @param     image the icon image to be displayed.
  637        * @see       #setIconImages
  638        * @see       #getIconImages()
  639        * @since     1.6
  640        */
  641       public void setIconImage(Image image) {
  642           ArrayList<Image> imageList = new ArrayList<Image>();
  643           if (image != null) {
  644               imageList.add(image);
  645           }
  646           setIconImages(imageList);
  647       }
  648   
  649       /**
  650        * Makes this Window displayable by creating the connection to its
  651        * native screen resource.
  652        * This method is called internally by the toolkit and should
  653        * not be called directly by programs.
  654        * @see Component#isDisplayable
  655        * @see Container#removeNotify
  656        * @since JDK1.0
  657        */
  658       public void addNotify() {
  659           synchronized (getTreeLock()) {
  660               Container parent = this.parent;
  661               if (parent != null && parent.getPeer() == null) {
  662                   parent.addNotify();
  663               }
  664               if (peer == null) {
  665                   peer = getToolkit().createWindow(this);
  666               }
  667               synchronized (allWindows) {
  668                   allWindows.add(this);
  669               }
  670               super.addNotify();
  671           }
  672       }
  673   
  674       /**
  675        * {@inheritDoc}
  676        */
  677       public void removeNotify() {
  678           synchronized (getTreeLock()) {
  679               synchronized (allWindows) {
  680                   allWindows.remove(this);
  681               }
  682               super.removeNotify();
  683           }
  684       }
  685   
  686       /**
  687        * Causes this Window to be sized to fit the preferred size
  688        * and layouts of its subcomponents. The resulting width and
  689        * height of the window are automatically enlarged if either
  690        * of dimensions is less than the minimum size as specified
  691        * by the previous call to the {@code setMinimumSize} method.
  692        * <p>
  693        * If the window and/or its owner are not displayable yet,
  694        * both of them are made displayable before calculating
  695        * the preferred size. The Window is validated after its
  696        * size is being calculated.
  697        *
  698        * @see Component#isDisplayable
  699        * @see #setMinimumSize
  700        */
  701       public void pack() {
  702           Container parent = this.parent;
  703           if (parent != null && parent.getPeer() == null) {
  704               parent.addNotify();
  705           }
  706           if (peer == null) {
  707               addNotify();
  708           }
  709           Dimension newSize = getPreferredSize();
  710           if (peer != null) {
  711               setClientSize(newSize.width, newSize.height);
  712           }
  713   
  714           if(beforeFirstShow) {
  715               isPacked = true;
  716           }
  717   
  718           validate();
  719       }
  720   
  721       /**
  722        * Sets the minimum size of this window to a constant
  723        * value.  Subsequent calls to {@code getMinimumSize}
  724        * will always return this value. If current window's
  725        * size is less than {@code minimumSize} the size of the
  726        * window is automatically enlarged to honor the minimum size.
  727        * <p>
  728        * If the {@code setSize} or {@code setBounds} methods
  729        * are called afterwards with a width or height less than
  730        * that was specified by the {@code setMinimumSize} method
  731        * the window is automatically enlarged to meet
  732        * the {@code minimumSize} value. The {@code minimumSize}
  733        * value also affects the behaviour of the {@code pack} method.
  734        * <p>
  735        * The default behavior is restored by setting the minimum size
  736        * parameter to the {@code null} value.
  737        * <p>
  738        * Resizing operation may be restricted if the user tries
  739        * to resize window below the {@code minimumSize} value.
  740        * This behaviour is platform-dependent.
  741        *
  742        * @param minimumSize the new minimum size of this window
  743        * @see Component#setMinimumSize
  744        * @see #getMinimumSize
  745        * @see #isMinimumSizeSet
  746        * @see #setSize(Dimension)
  747        * @see #pack
  748        * @since 1.6
  749        */
  750       public void setMinimumSize(Dimension minimumSize) {
  751           synchronized (getTreeLock()) {
  752               super.setMinimumSize(minimumSize);
  753               Dimension size = getSize();
  754               if (isMinimumSizeSet()) {
  755                   if (size.width < minimumSize.width || size.height < minimumSize.height) {
  756                       int nw = Math.max(width, minimumSize.width);
  757                       int nh = Math.max(height, minimumSize.height);
  758                       setSize(nw, nh);
  759                   }
  760               }
  761               if (peer != null) {
  762                   ((WindowPeer)peer).updateMinimumSize();
  763               }
  764           }
  765       }
  766   
  767       /**
  768        * {@inheritDoc}
  769        * <p>
  770        * The {@code d.width} and {@code d.height} values
  771        * are automatically enlarged if either is less than
  772        * the minimum size as specified by previous call to
  773        * {@code setMinimumSize}.
  774        *
  775        * @see #getSize
  776        * @see #setBounds
  777        * @see #setMinimumSize
  778        * @since 1.6
  779        */
  780       public void setSize(Dimension d) {
  781           super.setSize(d);
  782       }
  783   
  784       /**
  785        * {@inheritDoc}
  786        * <p>
  787        * The {@code width} and {@code height} values
  788        * are automatically enlarged if either is less than
  789        * the minimum size as specified by previous call to
  790        * {@code setMinimumSize}.
  791        *
  792        * @see #getSize
  793        * @see #setBounds
  794        * @see #setMinimumSize
  795        * @since 1.6
  796        */
  797       public void setSize(int width, int height) {
  798           super.setSize(width, height);
  799       }
  800   
  801       /**
  802        * @deprecated As of JDK version 1.1,
  803        * replaced by <code>setBounds(int, int, int, int)</code>.
  804        */
  805       @Deprecated
  806       public void reshape(int x, int y, int width, int height) {
  807           if (isMinimumSizeSet()) {
  808               Dimension minSize = getMinimumSize();
  809               if (width < minSize.width) {
  810                   width = minSize.width;
  811               }
  812               if (height < minSize.height) {
  813                   height = minSize.height;
  814               }
  815           }
  816           super.reshape(x, y, width, height);
  817       }
  818   
  819       void setClientSize(int w, int h) {
  820           synchronized (getTreeLock()) {
  821               setBoundsOp(ComponentPeer.SET_CLIENT_SIZE);
  822               setBounds(x, y, w, h);
  823           }
  824       }
  825   
  826       static private final AtomicBoolean
  827           beforeFirstWindowShown = new AtomicBoolean(true);
  828   
  829       final void closeSplashScreen() {
  830           if (isTrayIconWindow) {
  831               return;
  832           }
  833           if (beforeFirstWindowShown.getAndSet(false)) {
  834               SunToolkit.closeSplashScreen();
  835           }
  836       }
  837   
  838       /**
  839        * Shows or hides this {@code Window} depending on the value of parameter
  840        * {@code b}.
  841        * <p>
  842        * If the method shows the window then the window is also made
  843        * focused under the following conditions:
  844        * <ul>
  845        * <li> The {@code Window} meets the requirements outlined in the
  846        *      {@link #isFocusableWindow} method.
  847        * <li> The {@code Window}'s {@code autoRequestFocus} property is of the {@code true} value.
  848        * <li> Native windowing system allows the {@code Window} to get focused.
  849        * </ul>
  850        * There is an exception for the second condition (the value of the
  851        * {@code autoRequestFocus} property). The property is not taken into account if the
  852        * window is a modal dialog, which blocks the currently focused window.
  853        * <p>
  854        * Developers must never assume that the window is the focused or active window
  855        * until it receives a WINDOW_GAINED_FOCUS or WINDOW_ACTIVATED event.
  856        * @param b  if {@code true}, makes the {@code Window} visible,
  857        * otherwise hides the {@code Window}.
  858        * If the {@code Window} and/or its owner
  859        * are not yet displayable, both are made displayable.  The
  860        * {@code Window} will be validated prior to being made visible.
  861        * If the {@code Window} is already visible, this will bring the
  862        * {@code Window} to the front.<p>
  863        * If {@code false}, hides this {@code Window}, its subcomponents, and all
  864        * of its owned children.
  865        * The {@code Window} and its subcomponents can be made visible again
  866        * with a call to {@code #setVisible(true)}.
  867        * @see java.awt.Component#isDisplayable
  868        * @see java.awt.Component#setVisible
  869        * @see java.awt.Window#toFront
  870        * @see java.awt.Window#dispose
  871        * @see java.awt.Window#setAutoRequestFocus
  872        * @see java.awt.Window#isFocusableWindow
  873        */
  874       public void setVisible(boolean b) {
  875           super.setVisible(b);
  876       }
  877   
  878       /**
  879        * Makes the Window visible. If the Window and/or its owner
  880        * are not yet displayable, both are made displayable.  The
  881        * Window will be validated prior to being made visible.
  882        * If the Window is already visible, this will bring the Window
  883        * to the front.
  884        * @see       Component#isDisplayable
  885        * @see       #toFront
  886        * @deprecated As of JDK version 1.5, replaced by
  887        * {@link #setVisible(boolean)}.
  888        */
  889       @Deprecated
  890       public void show() {
  891           if (peer == null) {
  892               addNotify();
  893           }
  894           validate();
  895   
  896           isInShow = true;
  897           if (visible) {
  898               toFront();
  899           } else {
  900               beforeFirstShow = false;
  901               closeSplashScreen();
  902               Dialog.checkShouldBeBlocked(this);
  903               super.show();
  904               locationByPlatform = false;
  905               for (int i = 0; i < ownedWindowList.size(); i++) {
  906                   Window child = ownedWindowList.elementAt(i).get();
  907                   if ((child != null) && child.showWithParent) {
  908                       child.show();
  909                       child.showWithParent = false;
  910                   }       // endif
  911               }   // endfor
  912               if (!isModalBlocked()) {
  913                   updateChildrenBlocking();
  914               } else {
  915                   // fix for 6532736: after this window is shown, its blocker
  916                   // should be raised to front
  917                   modalBlocker.toFront_NoClientCode();
  918               }
  919               if (this instanceof Frame || this instanceof Dialog) {
  920                   updateChildFocusableWindowState(this);
  921               }
  922           }
  923           isInShow = false;
  924   
  925           // If first time shown, generate WindowOpened event
  926           if ((state & OPENED) == 0) {
  927               postWindowEvent(WindowEvent.WINDOW_OPENED);
  928               state |= OPENED;
  929           }
  930       }
  931   
  932       static void updateChildFocusableWindowState(Window w) {
  933           if (w.getPeer() != null && w.isShowing()) {
  934               ((WindowPeer)w.getPeer()).updateFocusableWindowState();
  935           }
  936           for (int i = 0; i < w.ownedWindowList.size(); i++) {
  937               Window child = w.ownedWindowList.elementAt(i).get();
  938               if (child != null) {
  939                   updateChildFocusableWindowState(child);
  940               }
  941           }
  942       }
  943   
  944       synchronized void postWindowEvent(int id) {
  945           if (windowListener != null
  946               || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0
  947               ||  Toolkit.enabledOnToolkit(AWTEvent.WINDOW_EVENT_MASK)) {
  948               WindowEvent e = new WindowEvent(this, id);
  949               Toolkit.getEventQueue().postEvent(e);
  950           }
  951       }
  952   
  953       /**
  954        * Hide this Window, its subcomponents, and all of its owned children.
  955        * The Window and its subcomponents can be made visible again
  956        * with a call to {@code show}.
  957        * </p>
  958        * @see #show
  959        * @see #dispose
  960        * @deprecated As of JDK version 1.5, replaced by
  961        * {@link #setVisible(boolean)}.
  962        */
  963       @Deprecated
  964       public void hide() {
  965           synchronized(ownedWindowList) {
  966               for (int i = 0; i < ownedWindowList.size(); i++) {
  967                   Window child = ownedWindowList.elementAt(i).get();
  968                   if ((child != null) && child.visible) {
  969                       child.hide();
  970                       child.showWithParent = true;
  971                   }
  972               }
  973           }
  974           if (isModalBlocked()) {
  975               modalBlocker.unblockWindow(this);
  976           }
  977           super.hide();
  978       }
  979   
  980       final void clearMostRecentFocusOwnerOnHide() {
  981           /* do nothing */
  982       }
  983   
  984       /**
  985        * Releases all of the native screen resources used by this
  986        * <code>Window</code>, its subcomponents, and all of its owned
  987        * children. That is, the resources for these <code>Component</code>s
  988        * will be destroyed, any memory they consume will be returned to the
  989        * OS, and they will be marked as undisplayable.
  990        * <p>
  991        * The <code>Window</code> and its subcomponents can be made displayable
  992        * again by rebuilding the native resources with a subsequent call to
  993        * <code>pack</code> or <code>show</code>. The states of the recreated
  994        * <code>Window</code> and its subcomponents will be identical to the
  995        * states of these objects at the point where the <code>Window</code>
  996        * was disposed (not accounting for additional modifications between
  997        * those actions).
  998        * <p>
  999        * <b>Note</b>: When the last displayable window
 1000        * within the Java virtual machine (VM) is disposed of, the VM may
 1001        * terminate.  See <a href="doc-files/AWTThreadIssues.html#Autoshutdown">
 1002        * AWT Threading Issues</a> for more information.
 1003        * @see Component#isDisplayable
 1004        * @see #pack
 1005        * @see #show
 1006        */
 1007       public void dispose() {
 1008           doDispose();
 1009       }
 1010   
 1011       /*
 1012        * Fix for 4872170.
 1013        * If dispose() is called on parent then its children have to be disposed as well
 1014        * as reported in javadoc. So we need to implement this functionality even if a
 1015        * child overrides dispose() in a wrong way without calling super.dispose().
 1016        */
 1017       void disposeImpl() {
 1018           dispose();
 1019           if (getPeer() != null) {
 1020               doDispose();
 1021           }
 1022       }
 1023   
 1024       void doDispose() {
 1025       class DisposeAction implements Runnable {
 1026           public void run() {
 1027               // Check if this window is the fullscreen window for the
 1028               // device. Exit the fullscreen mode prior to disposing
 1029               // of the window if that's the case.
 1030               GraphicsDevice gd = getGraphicsConfiguration().getDevice();
 1031               if (gd.getFullScreenWindow() == Window.this) {
 1032                   gd.setFullScreenWindow(null);
 1033               }
 1034   
 1035               Object[] ownedWindowArray;
 1036               synchronized(ownedWindowList) {
 1037                   ownedWindowArray = new Object[ownedWindowList.size()];
 1038                   ownedWindowList.copyInto(ownedWindowArray);
 1039               }
 1040               for (int i = 0; i < ownedWindowArray.length; i++) {
 1041                   Window child = (Window) (((WeakReference)
 1042                                  (ownedWindowArray[i])).get());
 1043                   if (child != null) {
 1044                       child.disposeImpl();
 1045                   }
 1046               }
 1047               hide();
 1048               beforeFirstShow = true;
 1049               removeNotify();
 1050               synchronized (inputContextLock) {
 1051                   if (inputContext != null) {
 1052                       inputContext.dispose();
 1053                       inputContext = null;
 1054                   }
 1055               }
 1056               clearCurrentFocusCycleRootOnHide();
 1057           }
 1058       }
 1059           DisposeAction action = new DisposeAction();
 1060           if (EventQueue.isDispatchThread()) {
 1061               action.run();
 1062           }
 1063           else {
 1064               try {
 1065                   EventQueue.invokeAndWait(action);
 1066               }
 1067               catch (InterruptedException e) {
 1068                   System.err.println("Disposal was interrupted:");
 1069                   e.printStackTrace();
 1070               }
 1071               catch (InvocationTargetException e) {
 1072                   System.err.println("Exception during disposal:");
 1073                   e.printStackTrace();
 1074               }
 1075           }
 1076           // Execute outside the Runnable because postWindowEvent is
 1077           // synchronized on (this). We don't need to synchronize the call
 1078           // on the EventQueue anyways.
 1079           postWindowEvent(WindowEvent.WINDOW_CLOSED);
 1080       }
 1081   
 1082       /*
 1083        * Should only be called while holding the tree lock.
 1084        * It's overridden here because parent == owner in Window,
 1085        * and we shouldn't adjust counter on owner
 1086        */
 1087       void adjustListeningChildrenOnParent(long mask, int num) {
 1088       }
 1089   
 1090       // Should only be called while holding tree lock
 1091       void adjustDecendantsOnParent(int num) {
 1092           // do nothing since parent == owner and we shouldn't
 1093           // ajust counter on owner
 1094       }
 1095   
 1096       /**
 1097        * If this Window is visible, brings this Window to the front and may make
 1098        * it the focused Window.
 1099        * <p>
 1100        * Places this Window at the top of the stacking order and shows it in
 1101        * front of any other Windows in this VM. No action will take place if this
 1102        * Window is not visible. Some platforms do not allow Windows which own
 1103        * other Windows to appear on top of those owned Windows. Some platforms
 1104        * may not permit this VM to place its Windows above windows of native
 1105        * applications, or Windows of other VMs. This permission may depend on
 1106        * whether a Window in this VM is already focused. Every attempt will be
 1107        * made to move this Window as high as possible in the stacking order;
 1108        * however, developers should not assume that this method will move this
 1109        * Window above all other windows in every situation.
 1110        * <p>
 1111        * Developers must never assume that this Window is the focused or active
 1112        * Window until this Window receives a WINDOW_GAINED_FOCUS or WINDOW_ACTIVATED
 1113        * event. On platforms where the top-most window is the focused window, this
 1114        * method will <b>probably</b> focus this Window (if it is not already focused)
 1115        * under the following conditions:
 1116        * <ul>
 1117        * <li> The window meets the requirements outlined in the
 1118        *      {@link #isFocusableWindow} method.
 1119        * <li> The window's property {@code autoRequestFocus} is of the
 1120        *      {@code true} value.
 1121        * <li> Native windowing system allows the window to get focused.
 1122        * </ul>
 1123        * On platforms where the stacking order does not typically affect the focused
 1124        * window, this method will <b>probably</b> leave the focused and active
 1125        * Windows unchanged.
 1126        * <p>
 1127        * If this method causes this Window to be focused, and this Window is a
 1128        * Frame or a Dialog, it will also become activated. If this Window is
 1129        * focused, but it is not a Frame or a Dialog, then the first Frame or
 1130        * Dialog that is an owner of this Window will be activated.
 1131        * <p>
 1132        * If this window is blocked by modal dialog, then the blocking dialog
 1133        * is brought to the front and remains above the blocked window.
 1134        *
 1135        * @see       #toBack
 1136        * @see       #setAutoRequestFocus
 1137        * @see       #isFocusableWindow
 1138        */
 1139       public void toFront() {
 1140           toFront_NoClientCode();
 1141       }
 1142   
 1143       // This functionality is implemented in a final package-private method
 1144       // to insure that it cannot be overridden by client subclasses.
 1145       final void toFront_NoClientCode() {
 1146           if (visible) {
 1147               WindowPeer peer = (WindowPeer)this.peer;
 1148               if (peer != null) {
 1149                   peer.toFront();
 1150               }
 1151               if (isModalBlocked()) {
 1152                   modalBlocker.toFront_NoClientCode();
 1153               }
 1154           }
 1155       }
 1156   
 1157       /**
 1158        * If this Window is visible, sends this Window to the back and may cause
 1159        * it to lose focus or activation if it is the focused or active Window.
 1160        * <p>
 1161        * Places this Window at the bottom of the stacking order and shows it
 1162        * behind any other Windows in this VM. No action will take place is this
 1163        * Window is not visible. Some platforms do not allow Windows which are
 1164        * owned by other Windows to appear below their owners. Every attempt will
 1165        * be made to move this Window as low as possible in the stacking order;
 1166        * however, developers should not assume that this method will move this
 1167        * Window below all other windows in every situation.
 1168        * <p>
 1169        * Because of variations in native windowing systems, no guarantees about
 1170        * changes to the focused and active Windows can be made. Developers must
 1171        * never assume that this Window is no longer the focused or active Window
 1172        * until this Window receives a WINDOW_LOST_FOCUS or WINDOW_DEACTIVATED
 1173        * event. On platforms where the top-most window is the focused window,
 1174        * this method will <b>probably</b> cause this Window to lose focus. In
 1175        * that case, the next highest, focusable Window in this VM will receive
 1176        * focus. On platforms where the stacking order does not typically affect
 1177        * the focused window, this method will <b>probably</b> leave the focused
 1178        * and active Windows unchanged.
 1179        *
 1180        * @see       #toFront
 1181        */
 1182       public void toBack() {
 1183           toBack_NoClientCode();
 1184       }
 1185   
 1186       // This functionality is implemented in a final package-private method
 1187       // to insure that it cannot be overridden by client subclasses.
 1188       final void toBack_NoClientCode() {
 1189           if(isAlwaysOnTop()) {
 1190               try {
 1191                   setAlwaysOnTop(false);
 1192               }catch(SecurityException e) {
 1193               }
 1194           }
 1195           if (visible) {
 1196               WindowPeer peer = (WindowPeer)this.peer;
 1197               if (peer != null) {
 1198                   peer.toBack();
 1199               }
 1200           }
 1201       }
 1202   
 1203       /**
 1204        * Returns the toolkit of this frame.
 1205        * @return    the toolkit of this window.
 1206        * @see       Toolkit
 1207        * @see       Toolkit#getDefaultToolkit
 1208        * @see       Component#getToolkit
 1209        */
 1210       public Toolkit getToolkit() {
 1211           return Toolkit.getDefaultToolkit();
 1212       }
 1213   
 1214       /**
 1215        * Gets the warning string that is displayed with this window.
 1216        * If this window is insecure, the warning string is displayed
 1217        * somewhere in the visible area of the window. A window is
 1218        * insecure if there is a security manager, and the security
 1219        * manager's <code>checkTopLevelWindow</code> method returns
 1220        * <code>false</code> when this window is passed to it as an
 1221        * argument.
 1222        * <p>
 1223        * If the window is secure, then <code>getWarningString</code>
 1224        * returns <code>null</code>. If the window is insecure, this
 1225        * method checks for the system property
 1226        * <code>awt.appletWarning</code>
 1227        * and returns the string value of that property.
 1228        * @return    the warning string for this window.
 1229        * @see       java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object)
 1230        */
 1231       public final String getWarningString() {
 1232           return warningString;
 1233       }
 1234   
 1235       private void setWarningString() {
 1236           warningString = null;
 1237           SecurityManager sm = System.getSecurityManager();
 1238           if (sm != null) {
 1239               if (!sm.checkTopLevelWindow(this)) {
 1240                   // make sure the privileged action is only
 1241                   // for getting the property! We don't want the
 1242                   // above checkTopLevelWindow call to always succeed!
 1243                   warningString = (String) AccessController.doPrivileged(
 1244                         new GetPropertyAction("awt.appletWarning",
 1245                                               "Java Applet Window"));
 1246               }
 1247           }
 1248       }
 1249   
 1250       /**
 1251        * Gets the <code>Locale</code> object that is associated
 1252        * with this window, if the locale has been set.
 1253        * If no locale has been set, then the default locale
 1254        * is returned.
 1255        * @return    the locale that is set for this window.
 1256        * @see       java.util.Locale
 1257        * @since     JDK1.1
 1258        */
 1259       public Locale getLocale() {
 1260         if (this.locale == null) {
 1261           return Locale.getDefault();
 1262         }
 1263         return this.locale;
 1264       }
 1265   
 1266       /**
 1267        * Gets the input context for this window. A window always has an input context,
 1268        * which is shared by subcomponents unless they create and set their own.
 1269        * @see Component#getInputContext
 1270        * @since 1.2
 1271        */
 1272       public InputContext getInputContext() {
 1273           synchronized (inputContextLock) {
 1274               if (inputContext == null) {
 1275                   inputContext = InputContext.getInstance();
 1276               }
 1277           }
 1278           return inputContext;
 1279       }
 1280   
 1281       /**
 1282        * Set the cursor image to a specified cursor.
 1283        * <p>
 1284        * The method may have no visual effect if the Java platform
 1285        * implementation and/or the native system do not support
 1286        * changing the mouse cursor shape.
 1287        * @param     cursor One of the constants defined
 1288        *            by the <code>Cursor</code> class. If this parameter is null
 1289        *            then the cursor for this window will be set to the type
 1290        *            Cursor.DEFAULT_CURSOR.
 1291        * @see       Component#getCursor
 1292        * @see       Cursor
 1293        * @since     JDK1.1
 1294        */
 1295       public void setCursor(Cursor cursor) {
 1296           if (cursor == null) {
 1297               cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
 1298           }
 1299           super.setCursor(cursor);
 1300       }
 1301   
 1302       /**
 1303        * Returns the owner of this window.
 1304        * @since 1.2
 1305        */
 1306       public Window getOwner() {
 1307           return getOwner_NoClientCode();
 1308       }
 1309       final Window getOwner_NoClientCode() {
 1310           return (Window)parent;
 1311       }
 1312   
 1313       /**
 1314        * Return an array containing all the windows this
 1315        * window currently owns.
 1316        * @since 1.2
 1317        */
 1318       public Window[] getOwnedWindows() {
 1319           return getOwnedWindows_NoClientCode();
 1320       }
 1321       final Window[] getOwnedWindows_NoClientCode() {
 1322           Window realCopy[];
 1323   
 1324           synchronized(ownedWindowList) {
 1325               // Recall that ownedWindowList is actually a Vector of
 1326               // WeakReferences and calling get() on one of these references
 1327               // may return null. Make two arrays-- one the size of the
 1328               // Vector (fullCopy with size fullSize), and one the size of
 1329               // all non-null get()s (realCopy with size realSize).
 1330               int fullSize = ownedWindowList.size();
 1331               int realSize = 0;
 1332               Window fullCopy[] = new Window[fullSize];
 1333   
 1334               for (int i = 0; i < fullSize; i++) {
 1335                   fullCopy[realSize] = ownedWindowList.elementAt(i).get();
 1336   
 1337                   if (fullCopy[realSize] != null) {
 1338                       realSize++;
 1339                   }
 1340               }
 1341   
 1342               if (fullSize != realSize) {
 1343                   realCopy = Arrays.copyOf(fullCopy, realSize);
 1344               } else {
 1345                   realCopy = fullCopy;
 1346               }
 1347           }
 1348   
 1349           return realCopy;
 1350       }
 1351   
 1352       boolean isModalBlocked() {
 1353           return modalBlocker != null;
 1354       }
 1355   
 1356       void setModalBlocked(Dialog blocker, boolean blocked, boolean peerCall) {
 1357           this.modalBlocker = blocked ? blocker : null;
 1358           if (peerCall) {
 1359               WindowPeer peer = (WindowPeer)this.peer;
 1360               if (peer != null) {
 1361                   peer.setModalBlocked(blocker, blocked);
 1362               }
 1363           }
 1364       }
 1365   
 1366       Dialog getModalBlocker() {
 1367           return modalBlocker;
 1368       }
 1369   
 1370       /*
 1371        * Returns a list of all displayable Windows, i. e. all the
 1372        * Windows which peer is not null.
 1373        *
 1374        * @see #addNotify
 1375        * @see #removeNotify
 1376        */
 1377       static IdentityArrayList<Window> getAllWindows() {
 1378           synchronized (allWindows) {
 1379               IdentityArrayList<Window> v = new IdentityArrayList<Window>();
 1380               v.addAll(allWindows);
 1381               return v;
 1382           }
 1383       }
 1384   
 1385       static IdentityArrayList<Window> getAllUnblockedWindows() {
 1386           synchronized (allWindows) {
 1387               IdentityArrayList<Window> unblocked = new IdentityArrayList<Window>();
 1388               for (int i = 0; i < allWindows.size(); i++) {
 1389                   Window w = allWindows.get(i);
 1390                   if (!w.isModalBlocked()) {
 1391                       unblocked.add(w);
 1392                   }
 1393               }
 1394               return unblocked;
 1395           }
 1396       }
 1397   
 1398       private static Window[] getWindows(AppContext appContext) {
 1399           synchronized (Window.class) {
 1400               Window realCopy[];
 1401               Vector<WeakReference<Window>> windowList =
 1402                   (Vector<WeakReference<Window>>)appContext.get(Window.class);
 1403               if (windowList != null) {
 1404                   int fullSize = windowList.size();
 1405                   int realSize = 0;
 1406                   Window fullCopy[] = new Window[fullSize];
 1407                   for (int i = 0; i < fullSize; i++) {
 1408                       Window w = windowList.get(i).get();
 1409                       if (w != null) {
 1410                           fullCopy[realSize++] = w;
 1411                       }
 1412                   }
 1413                   if (fullSize != realSize) {
 1414                       realCopy = Arrays.copyOf(fullCopy, realSize);
 1415                   } else {
 1416                       realCopy = fullCopy;
 1417                   }
 1418               } else {
 1419                   realCopy = new Window[0];
 1420               }
 1421               return realCopy;
 1422           }
 1423       }
 1424   
 1425       /**
 1426        * Returns an array of all {@code Window}s, both owned and ownerless,
 1427        * created by this application.
 1428        * If called from an applet, the array includes only the {@code Window}s
 1429        * accessible by that applet.
 1430        * <p>
 1431        * <b>Warning:</b> this method may return system created windows, such
 1432        * as a print dialog. Applications should not assume the existence of
 1433        * these dialogs, nor should an application assume anything about these
 1434        * dialogs such as component positions, <code>LayoutManager</code>s
 1435        * or serialization.
 1436        *
 1437        * @see Frame#getFrames
 1438        * @see Window#getOwnerlessWindows
 1439        *
 1440        * @since 1.6
 1441        */
 1442       public static Window[] getWindows() {
 1443           return getWindows(AppContext.getAppContext());
 1444       }
 1445   
 1446       /**
 1447        * Returns an array of all {@code Window}s created by this application
 1448        * that have no owner. They include {@code Frame}s and ownerless
 1449        * {@code Dialog}s and {@code Window}s.
 1450        * If called from an applet, the array includes only the {@code Window}s
 1451        * accessible by that applet.
 1452        * <p>
 1453        * <b>Warning:</b> this method may return system created windows, such
 1454        * as a print dialog. Applications should not assume the existence of
 1455        * these dialogs, nor should an application assume anything about these
 1456        * dialogs such as component positions, <code>LayoutManager</code>s
 1457        * or serialization.
 1458        *
 1459        * @see Frame#getFrames
 1460        * @see Window#getWindows()
 1461        *
 1462        * @since 1.6
 1463        */
 1464       public static Window[] getOwnerlessWindows() {
 1465           Window[] allWindows = Window.getWindows();
 1466   
 1467           int ownerlessCount = 0;
 1468           for (Window w : allWindows) {
 1469               if (w.getOwner() == null) {
 1470                   ownerlessCount++;
 1471               }
 1472           }
 1473   
 1474           Window[] ownerless = new Window[ownerlessCount];
 1475           int c = 0;
 1476           for (Window w : allWindows) {
 1477               if (w.getOwner() == null) {
 1478                   ownerless[c++] = w;
 1479               }
 1480           }
 1481   
 1482           return ownerless;
 1483       }
 1484   
 1485       Window getDocumentRoot() {
 1486           synchronized (getTreeLock()) {
 1487               Window w = this;
 1488               while (w.getOwner() != null) {
 1489                   w = w.getOwner();
 1490               }
 1491               return w;
 1492           }
 1493       }
 1494   
 1495       /**
 1496        * Specifies the modal exclusion type for this window. If a window is modal
 1497        * excluded, it is not blocked by some modal dialogs. See {@link
 1498        * java.awt.Dialog.ModalExclusionType Dialog.ModalExclusionType} for
 1499        * possible modal exclusion types.
 1500        * <p>
 1501        * If the given type is not supported, <code>NO_EXCLUDE</code> is used.
 1502        * <p>
 1503        * Note: changing the modal exclusion type for a visible window may have no
 1504        * effect until it is hidden and then shown again.
 1505        *
 1506        * @param exclusionType the modal exclusion type for this window; a <code>null</code>
 1507        *     value is equivivalent to {@link Dialog.ModalExclusionType#NO_EXCLUDE
 1508        *     NO_EXCLUDE}
 1509        * @throws SecurityException if the calling thread does not have permission
 1510        *     to set the modal exclusion property to the window with the given
 1511        *     <code>exclusionType</code>
 1512        * @see java.awt.Dialog.ModalExclusionType
 1513        * @see java.awt.Window#getModalExclusionType
 1514        * @see java.awt.Toolkit#isModalExclusionTypeSupported
 1515        *
 1516        * @since 1.6
 1517        */
 1518       public void setModalExclusionType(Dialog.ModalExclusionType exclusionType) {
 1519           if (exclusionType == null) {
 1520               exclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
 1521           }
 1522           if (!Toolkit.getDefaultToolkit().isModalExclusionTypeSupported(exclusionType)) {
 1523               exclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
 1524           }
 1525           if (modalExclusionType == exclusionType) {
 1526               return;
 1527           }
 1528           if (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE) {
 1529               SecurityManager sm = System.getSecurityManager();
 1530               if (sm != null) {
 1531                   sm.checkPermission(SecurityConstants.TOOLKIT_MODALITY_PERMISSION);
 1532               }
 1533           }
 1534           modalExclusionType = exclusionType;
 1535   
 1536           // if we want on-fly changes, we need to uncomment the lines below
 1537           //   and override the method in Dialog to use modalShow() instead
 1538           //   of updateChildrenBlocking()
 1539    /*
 1540           if (isModalBlocked()) {
 1541               modalBlocker.unblockWindow(this);
 1542           }
 1543           Dialog.checkShouldBeBlocked(this);
 1544           updateChildrenBlocking();
 1545    */
 1546       }
 1547   
 1548       /**
 1549        * Returns the modal exclusion type of this window.
 1550        *
 1551        * @return the modal exclusion type of this window
 1552        *
 1553        * @see java.awt.Dialog.ModalExclusionType
 1554        * @see java.awt.Window#setModalExclusionType
 1555        *
 1556        * @since 1.6
 1557        */
 1558       public Dialog.ModalExclusionType getModalExclusionType() {
 1559           return modalExclusionType;
 1560       }
 1561   
 1562       boolean isModalExcluded(Dialog.ModalExclusionType exclusionType) {
 1563           if ((modalExclusionType != null) &&
 1564               modalExclusionType.compareTo(exclusionType) >= 0)
 1565           {
 1566               return true;
 1567           }
 1568           Window owner = getOwner_NoClientCode();
 1569           return (owner != null) && owner.isModalExcluded(exclusionType);
 1570       }
 1571   
 1572       void updateChildrenBlocking() {
 1573           Vector<Window> childHierarchy = new Vector<Window>();
 1574           Window[] ownedWindows = getOwnedWindows();
 1575           for (int i = 0; i < ownedWindows.length; i++) {
 1576               childHierarchy.add(ownedWindows[i]);
 1577           }
 1578           int k = 0;
 1579           while (k < childHierarchy.size()) {
 1580               Window w = childHierarchy.get(k);
 1581               if (w.isVisible()) {
 1582                   if (w.isModalBlocked()) {
 1583                       Dialog blocker = w.getModalBlocker();
 1584                       blocker.unblockWindow(w);
 1585                   }
 1586                   Dialog.checkShouldBeBlocked(w);
 1587                   Window[] wOwned = w.getOwnedWindows();
 1588                   for (int j = 0; j < wOwned.length; j++) {
 1589                       childHierarchy.add(wOwned[j]);
 1590                   }
 1591               }
 1592               k++;
 1593           }
 1594       }
 1595   
 1596       /**
 1597        * Adds the specified window listener to receive window events from
 1598        * this window.
 1599        * If l is null, no exception is thrown and no action is performed.
 1600        * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 1601        * >AWT Threading Issues</a> for details on AWT's threading model.
 1602        *
 1603        * @param   l the window listener
 1604        * @see #removeWindowListener
 1605        * @see #getWindowListeners
 1606        */
 1607       public synchronized void addWindowListener(WindowListener l) {
 1608           if (l == null) {
 1609               return;
 1610           }
 1611           newEventsOnly = true;
 1612           windowListener = AWTEventMulticaster.add(windowListener, l);
 1613       }
 1614   
 1615       /**
 1616        * Adds the specified window state listener to receive window
 1617        * events from this window.  If <code>l</code> is <code>null</code>,
 1618        * no exception is thrown and no action is performed.
 1619        * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 1620        * >AWT Threading Issues</a> for details on AWT's threading model.
 1621        *
 1622        * @param   l the window state listener
 1623        * @see #removeWindowStateListener
 1624        * @see #getWindowStateListeners
 1625        * @since 1.4
 1626        */
 1627       public synchronized void addWindowStateListener(WindowStateListener l) {
 1628           if (l == null) {
 1629               return;
 1630           }
 1631           windowStateListener = AWTEventMulticaster.add(windowStateListener, l);
 1632           newEventsOnly = true;
 1633       }
 1634   
 1635       /**
 1636        * Adds the specified window focus listener to receive window events
 1637        * from this window.
 1638        * If l is null, no exception is thrown and no action is performed.
 1639        * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 1640        * >AWT Threading Issues</a> for details on AWT's threading model.
 1641        *
 1642        * @param   l the window focus listener
 1643        * @see #removeWindowFocusListener
 1644        * @see #getWindowFocusListeners
 1645        * @since 1.4
 1646        */
 1647       public synchronized void addWindowFocusListener(WindowFocusListener l) {
 1648           if (l == null) {
 1649               return;
 1650           }
 1651           windowFocusListener = AWTEventMulticaster.add(windowFocusListener, l);
 1652           newEventsOnly = true;
 1653       }
 1654   
 1655       /**
 1656        * Removes the specified window listener so that it no longer
 1657        * receives window events from this window.
 1658        * If l is null, no exception is thrown and no action is performed.
 1659        * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 1660        * >AWT Threading Issues</a> for details on AWT's threading model.
 1661        *
 1662        * @param   l the window listener
 1663        * @see #addWindowListener
 1664        * @see #getWindowListeners
 1665        */
 1666       public synchronized void removeWindowListener(WindowListener l) {
 1667           if (l == null) {
 1668               return;
 1669           }
 1670           windowListener = AWTEventMulticaster.remove(windowListener, l);
 1671       }
 1672   
 1673       /**
 1674        * Removes the specified window state listener so that it no
 1675        * longer receives window events from this window.  If
 1676        * <code>l</code> is <code>null</code>, no exception is thrown and
 1677        * no action is performed.
 1678        * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 1679        * >AWT Threading Issues</a> for details on AWT's threading model.
 1680        *
 1681        * @param   l the window state listener
 1682        * @see #addWindowStateListener
 1683        * @see #getWindowStateListeners
 1684        * @since 1.4
 1685        */
 1686       public synchronized void removeWindowStateListener(WindowStateListener l) {
 1687           if (l == null) {
 1688               return;
 1689           }
 1690           windowStateListener = AWTEventMulticaster.remove(windowStateListener, l);
 1691       }
 1692   
 1693       /**
 1694        * Removes the specified window focus listener so that it no longer
 1695        * receives window events from this window.
 1696        * If l is null, no exception is thrown and no action is performed.
 1697        * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
 1698        * >AWT Threading Issues</a> for details on AWT's threading model.
 1699        *
 1700        * @param   l the window focus listener
 1701        * @see #addWindowFocusListener
 1702        * @see #getWindowFocusListeners
 1703        * @since 1.4
 1704        */
 1705       public synchronized void removeWindowFocusListener(WindowFocusListener l) {
 1706           if (l == null) {
 1707               return;
 1708           }
 1709           windowFocusListener = AWTEventMulticaster.remove(windowFocusListener, l);
 1710       }
 1711   
 1712       /**
 1713        * Returns an array of all the window listeners
 1714        * registered on this window.
 1715        *
 1716        * @return all of this window's <code>WindowListener</code>s
 1717        *         or an empty array if no window
 1718        *         listeners are currently registered
 1719        *
 1720        * @see #addWindowListener
 1721        * @see #removeWindowListener
 1722        * @since 1.4
 1723        */
 1724       public synchronized WindowListener[] getWindowListeners() {
 1725           return (WindowListener[])(getListeners(WindowListener.class));
 1726       }
 1727   
 1728       /**
 1729        * Returns an array of all the window focus listeners
 1730        * registered on this window.
 1731        *
 1732        * @return all of this window's <code>WindowFocusListener</code>s
 1733        *         or an empty array if no window focus
 1734        *         listeners are currently registered
 1735        *
 1736        * @see #addWindowFocusListener
 1737        * @see #removeWindowFocusListener
 1738        * @since 1.4
 1739        */
 1740       public synchronized WindowFocusListener[] getWindowFocusListeners() {
 1741           return (WindowFocusListener[])(getListeners(WindowFocusListener.class));
 1742       }
 1743   
 1744       /**
 1745        * Returns an array of all the window state listeners
 1746        * registered on this window.
 1747        *
 1748        * @return all of this window's <code>WindowStateListener</code>s
 1749        *         or an empty array if no window state
 1750        *         listeners are currently registered
 1751        *
 1752        * @see #addWindowStateListener
 1753        * @see #removeWindowStateListener
 1754        * @since 1.4
 1755        */
 1756       public synchronized WindowStateListener[] getWindowStateListeners() {
 1757           return (WindowStateListener[])(getListeners(WindowStateListener.class));
 1758       }
 1759   
 1760   
 1761       /**
 1762        * Returns an array of all the objects currently registered
 1763        * as <code><em>Foo</em>Listener</code>s
 1764        * upon this <code>Window</code>.
 1765        * <code><em>Foo</em>Listener</code>s are registered using the
 1766        * <code>add<em>Foo</em>Listener</code> method.
 1767        *
 1768        * <p>
 1769        *
 1770        * You can specify the <code>listenerType</code> argument
 1771        * with a class literal, such as
 1772        * <code><em>Foo</em>Listener.class</code>.
 1773        * For example, you can query a
 1774        * <code>Window</code> <code>w</code>
 1775        * for its window listeners with the following code:
 1776        *
 1777        * <pre>WindowListener[] wls = (WindowListener[])(w.getListeners(WindowListener.class));</pre>
 1778        *
 1779        * If no such listeners exist, this method returns an empty array.
 1780        *
 1781        * @param listenerType the type of listeners requested; this parameter
 1782        *          should specify an interface that descends from
 1783        *          <code>java.util.EventListener</code>
 1784        * @return an array of all objects registered as
 1785        *          <code><em>Foo</em>Listener</code>s on this window,
 1786        *          or an empty array if no such
 1787        *          listeners have been added
 1788        * @exception ClassCastException if <code>listenerType</code>
 1789        *          doesn't specify a class or interface that implements
 1790        *          <code>java.util.EventListener</code>
 1791        *
 1792        * @see #getWindowListeners
 1793        * @since 1.3
 1794        */
 1795       public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
 1796           EventListener l = null;
 1797           if (listenerType == WindowFocusListener.class) {
 1798               l = windowFocusListener;
 1799           } else if (listenerType == WindowStateListener.class) {
 1800               l = windowStateListener;
 1801           } else if (listenerType == WindowListener.class) {
 1802               l = windowListener;
 1803           } else {
 1804               return super.getListeners(listenerType);
 1805           }
 1806           return AWTEventMulticaster.getListeners(l, listenerType);
 1807       }
 1808   
 1809       // REMIND: remove when filtering is handled at lower level
 1810       boolean eventEnabled(AWTEvent e) {
 1811           switch(e.id) {
 1812             case WindowEvent.WINDOW_OPENED:
 1813             case WindowEvent.WINDOW_CLOSING:
 1814             case WindowEvent.WINDOW_CLOSED:
 1815             case WindowEvent.WINDOW_ICONIFIED:
 1816             case WindowEvent.WINDOW_DEICONIFIED:
 1817             case WindowEvent.WINDOW_ACTIVATED:
 1818             case WindowEvent.WINDOW_DEACTIVATED:
 1819               if ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 ||
 1820                   windowListener != null) {
 1821                   return true;
 1822               }
 1823               return false;
 1824             case WindowEvent.WINDOW_GAINED_FOCUS:
 1825             case WindowEvent.WINDOW_LOST_FOCUS:
 1826               if ((eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0 ||
 1827                   windowFocusListener != null) {
 1828                   return true;
 1829               }
 1830               return false;
 1831             case WindowEvent.WINDOW_STATE_CHANGED:
 1832               if ((eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0 ||
 1833                   windowStateListener != null) {
 1834                   return true;
 1835               }
 1836               return false;
 1837             default:
 1838               break;
 1839           }
 1840           return super.eventEnabled(e);
 1841       }
 1842   
 1843       /**
 1844        * Processes events on this window. If the event is an
 1845        * <code>WindowEvent</code>, it invokes the
 1846        * <code>processWindowEvent</code> method, else it invokes its
 1847        * superclass's <code>processEvent</code>.
 1848        * <p>Note that if the event parameter is <code>null</code>
 1849        * the behavior is unspecified and may result in an
 1850        * exception.
 1851        *
 1852        * @param e the event
 1853        */
 1854       protected void processEvent(AWTEvent e) {
 1855           if (e instanceof WindowEvent) {
 1856               switch (e.getID()) {
 1857                   case WindowEvent.WINDOW_OPENED:
 1858                   case WindowEvent.WINDOW_CLOSING:
 1859                   case WindowEvent.WINDOW_CLOSED:
 1860                   case WindowEvent.WINDOW_ICONIFIED:
 1861                   case WindowEvent.WINDOW_DEICONIFIED:
 1862                   case WindowEvent.WINDOW_ACTIVATED:
 1863                   case WindowEvent.WINDOW_DEACTIVATED:
 1864                       processWindowEvent((WindowEvent)e);
 1865                       break;
 1866                   case WindowEvent.WINDOW_GAINED_FOCUS:
 1867                   case WindowEvent.WINDOW_LOST_FOCUS:
 1868                       processWindowFocusEvent((WindowEvent)e);
 1869                       break;
 1870                   case WindowEvent.WINDOW_STATE_CHANGED:
 1871                       processWindowStateEvent((WindowEvent)e);
 1872                   default:
 1873                       break;
 1874               }
 1875               return;
 1876           }
 1877           super.processEvent(e);
 1878       }
 1879   
 1880       /**
 1881        * Processes window events occurring on this window by
 1882        * dispatching them to any registered WindowListener objects.
 1883        * NOTE: This method will not be called unless window events
 1884        * are enabled for this component; this happens when one of the
 1885        * following occurs:
 1886        * <ul>
 1887        * <li>A WindowListener object is registered via
 1888        *     <code>addWindowListener</code>
 1889        * <li>Window events are enabled via <code>enableEvents</code>
 1890        * </ul>
 1891        * <p>Note that if the event parameter is <code>null</code>
 1892        * the behavior is unspecified and may result in an
 1893        * exception.
 1894        *
 1895        * @param e the window event
 1896        * @see Component#enableEvents
 1897        */
 1898       protected void processWindowEvent(WindowEvent e) {
 1899           WindowListener listener = windowListener;
 1900           if (listener != null) {
 1901               switch(e.getID()) {
 1902                   case WindowEvent.WINDOW_OPENED:
 1903                       listener.windowOpened(e);
 1904                       break;
 1905                   case WindowEvent.WINDOW_CLOSING:
 1906                       listener.windowClosing(e);
 1907                       break;
 1908                   case WindowEvent.WINDOW_CLOSED:
 1909                       listener.windowClosed(e);
 1910                       break;
 1911                   case WindowEvent.WINDOW_ICONIFIED:
 1912                       listener.windowIconified(e);
 1913                       break;
 1914                   case WindowEvent.WINDOW_DEICONIFIED:
 1915                       listener.windowDeiconified(e);
 1916                       break;
 1917                   case WindowEvent.WINDOW_ACTIVATED:
 1918                       listener.windowActivated(e);
 1919                       break;
 1920                   case WindowEvent.WINDOW_DEACTIVATED:
 1921                       listener.windowDeactivated(e);
 1922                       break;
 1923                   default:
 1924                       break;
 1925               }
 1926           }
 1927       }
 1928   
 1929       /**
 1930        * Processes window focus event occuring on this window by
 1931        * dispatching them to any registered WindowFocusListener objects.
 1932        * NOTE: this method will not be called unless window focus events
 1933        * are enabled for this window. This happens when one of the
 1934        * following occurs:
 1935        * <ul>
 1936        * <li>a WindowFocusListener is registered via
 1937        *     <code>addWindowFocusListener</code>
 1938        * <li>Window focus events are enabled via <code>enableEvents</code>
 1939        * </ul>
 1940        * <p>Note that if the event parameter is <code>null</code>
 1941        * the behavior is unspecified and may result in an
 1942        * exception.
 1943        *
 1944        * @param e the window focus event
 1945        * @see Component#enableEvents
 1946        * @since 1.4
 1947        */
 1948       protected void processWindowFocusEvent(WindowEvent e) {
 1949           WindowFocusListener listener = windowFocusListener;
 1950           if (listener != null) {
 1951               switch (e.getID()) {
 1952                   case WindowEvent.WINDOW_GAINED_FOCUS:
 1953                       listener.windowGainedFocus(e);
 1954                       break;
 1955                   case WindowEvent.WINDOW_LOST_FOCUS:
 1956                       listener.windowLostFocus(e);
 1957                       break;
 1958                   default:
 1959                       break;
 1960               }
 1961           }
 1962       }
 1963   
 1964       /**
 1965        * Processes window state event occuring on this window by
 1966        * dispatching them to any registered <code>WindowStateListener</code>
 1967        * objects.
 1968        * NOTE: this method will not be called unless window state events
 1969        * are enabled for this window.  This happens when one of the
 1970        * following occurs:
 1971        * <ul>
 1972        * <li>a <code>WindowStateListener</code> is registered via
 1973        *    <code>addWindowStateListener</code>
 1974        * <li>window state events are enabled via <code>enableEvents</code>
 1975        * </ul>
 1976        * <p>Note that if the event parameter is <code>null</code>
 1977        * the behavior is unspecified and may result in an
 1978        * exception.
 1979        *
 1980        * @param e the window state event
 1981        * @see java.awt.Component#enableEvents
 1982        * @since 1.4
 1983        */
 1984       protected void processWindowStateEvent(WindowEvent e) {
 1985           WindowStateListener listener = windowStateListener;
 1986           if (listener != null) {
 1987               switch (e.getID()) {
 1988                   case WindowEvent.WINDOW_STATE_CHANGED:
 1989                       listener.windowStateChanged(e);
 1990                       break;
 1991                   default:
 1992                       break;
 1993               }
 1994           }
 1995       }
 1996   
 1997       /**
 1998        * Implements a debugging hook -- checks to see if
 1999        * the user has typed <i>control-shift-F1</i>.  If so,
 2000        * the list of child windows is dumped to <code>System.out</code>.
 2001        * @param e  the keyboard event
 2002        */
 2003       void preProcessKeyEvent(KeyEvent e) {
 2004           // Dump the list of child windows to System.out.
 2005           if (e.isActionKey() && e.getKeyCode() == KeyEvent.VK_F1 &&
 2006               e.isControlDown() && e.isShiftDown() &&
 2007               e.getID() == KeyEvent.KEY_PRESSED) {
 2008               list(System.out, 0);
 2009           }
 2010       }
 2011   
 2012       void postProcessKeyEvent(KeyEvent e) {
 2013           // Do nothing
 2014       }
 2015   
 2016   
 2017       /**
 2018        * Sets whether this window should always be above other windows.  If
 2019        * there are multiple always-on-top windows, their relative order is
 2020        * unspecified and platform dependent.
 2021        * <p>
 2022        * If some other window is already always-on-top then the
 2023        * relative order between these windows is unspecified (depends on
 2024        * platform).  No window can be brought to be over the always-on-top
 2025        * window except maybe another always-on-top window.
 2026        * <p>
 2027        * All windows owned by an always-on-top window inherit this state and
 2028        * automatically become always-on-top.  If a window ceases to be
 2029        * always-on-top, the windows that it owns will no longer be
 2030        * always-on-top.  When an always-on-top window is sent {@link #toBack
 2031        * toBack}, its always-on-top state is set to <code>false</code>.
 2032        *
 2033        * <p> When this method is called on a window with a value of
 2034        * <code>true</code>, and the window is visible and the platform
 2035        * supports always-on-top for this window, the window is immediately
 2036        * brought forward, "sticking" it in the top-most position. If the
 2037        * window isn`t currently visible, this method sets the always-on-top
 2038        * state to <code>true</code> but does not bring the window forward.
 2039        * When the window is later shown, it will be always-on-top.
 2040        *
 2041        * <p> When this method is called on a window with a value of
 2042        * <code>false</code> the always-on-top state is set to normal. The
 2043        * window remains in the top-most position but it`s z-order can be
 2044        * changed as for any other window.  Calling this method with a value
 2045        * of <code>false</code> on a window that has a normal state has no
 2046        * effect.  Setting the always-on-top state to false has no effect on
 2047        * the relative z-order of the windows if there are no other
 2048        * always-on-top windows.
 2049        *
 2050        * <p><b>Note</b>: some platforms might not support always-on-top
 2051        * windows.  To detect if always-on-top windows are supported by the
 2052        * current platform, use {@link Toolkit#isAlwaysOnTopSupported()} and
 2053        * {@link Window#isAlwaysOnTopSupported()}.  If always-on-top mode
 2054        * isn't supported by the toolkit or for this window, calling this
 2055        * method has no effect.
 2056        * <p>
 2057        * If a SecurityManager is installed, the calling thread must be
 2058        * granted the AWTPermission "setWindowAlwaysOnTop" in
 2059        * order to set the value of this property. If this
 2060        * permission is not granted, this method will throw a
 2061        * SecurityException, and the current value of the property will
 2062        * be left unchanged.
 2063        *
 2064        * @param alwaysOnTop true if the window should always be above other
 2065        *        windows
 2066        * @throws SecurityException if the calling thread does not have
 2067        *         permission to set the value of always-on-top property
 2068        * @see #isAlwaysOnTop
 2069        * @see #toFront
 2070        * @see #toBack
 2071        * @see AWTPermission
 2072        * @see #isAlwaysOnTopSupported
 2073        * @see Toolkit#isAlwaysOnTopSupported
 2074        * @since 1.5
 2075        */
 2076       public final void setAlwaysOnTop(boolean alwaysOnTop) throws SecurityException {
 2077           SecurityManager security = System.getSecurityManager();
 2078           if (security != null) {
 2079               security.checkPermission(SecurityConstants.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION);
 2080           }
 2081   
 2082           boolean oldAlwaysOnTop;
 2083           synchronized(this) {
 2084               oldAlwaysOnTop = this.alwaysOnTop;
 2085               this.alwaysOnTop = alwaysOnTop;
 2086           }
 2087           if (oldAlwaysOnTop != alwaysOnTop ) {
 2088               if (isAlwaysOnTopSupported()) {
 2089                   WindowPeer peer = (WindowPeer)this.peer;
 2090                   synchronized(getTreeLock()) {
 2091                       if (peer != null) {
 2092                           peer.setAlwaysOnTop(alwaysOnTop);
 2093                       }
 2094                   }
 2095               }
 2096               firePropertyChange("alwaysOnTop", oldAlwaysOnTop, alwaysOnTop);
 2097           }
 2098       }
 2099   
 2100       /**
 2101        * Returns whether the always-on-top mode is supported for this
 2102        * window. Some platforms may not support always-on-top windows, some
 2103        * may support only some kinds of top-level windows; for example,
 2104        * a platform may not support always-on-top modal dialogs.
 2105        * @return <code>true</code>, if the always-on-top mode is
 2106        *         supported by the toolkit and for this window,
 2107        *         <code>false</code>, if always-on-top mode is not supported
 2108        *         for this window or toolkit doesn't support always-on-top windows.
 2109        * @see #setAlwaysOnTop(boolean)
 2110        * @see Toolkit#isAlwaysOnTopSupported
 2111        * @since 1.6
 2112        */
 2113       public boolean isAlwaysOnTopSupported() {
 2114           return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
 2115       }
 2116   
 2117   
 2118       /**
 2119        * Returns whether this window is an always-on-top window.
 2120        * @return <code>true</code>, if the window is in always-on-top state,
 2121        *         <code>false</code> otherwise
 2122        * @see #setAlwaysOnTop
 2123        * @since 1.5
 2124        */
 2125       public final boolean isAlwaysOnTop() {
 2126           return alwaysOnTop;
 2127       }
 2128   
 2129   
 2130       /**
 2131        * Returns the child Component of this Window that has focus if this Window
 2132        * is focused; returns null otherwise.
 2133        *
 2134        * @return the child Component with focus, or null if this Window is not
 2135        *         focused
 2136        * @see #getMostRecentFocusOwner
 2137        * @see #isFocused
 2138        */
 2139       public Component getFocusOwner() {
 2140           return (isFocused())
 2141               ? KeyboardFocusManager.getCurrentKeyboardFocusManager().
 2142                     getFocusOwner()
 2143               : null;
 2144       }
 2145   
 2146       /**
 2147        * Returns the child Component of this Window that will receive the focus
 2148        * when this Window is focused. If this Window is currently focused, this
 2149        * method returns the same Component as <code>getFocusOwner()</code>. If
 2150        * this Window is not focused, then the child Component that most recently
 2151        * requested focus will be returned. If no child Component has ever
 2152        * requested focus, and this is a focusable Window, then this Window's
 2153        * initial focusable Component is returned. If no child Component has ever
 2154        * requested focus, and this is a non-focusable Window, null is returned.
 2155        *
 2156        * @return the child Component that will receive focus when this Window is
 2157        *         focused
 2158        * @see #getFocusOwner
 2159        * @see #isFocused
 2160        * @see #isFocusableWindow
 2161        * @since 1.4
 2162        */
 2163       public Component getMostRecentFocusOwner() {
 2164           if (isFocused()) {
 2165               return getFocusOwner();
 2166           } else {
 2167               Component mostRecent =
 2168                   KeyboardFocusManager.getMostRecentFocusOwner(this);
 2169               if (mostRecent != null) {
 2170                   return mostRecent;
 2171               } else {
 2172                   return (isFocusableWindow())
 2173                       ? getFocusTraversalPolicy().getInitialComponent(this)
 2174                       : null;
 2175               }
 2176           }
 2177       }
 2178   
 2179       /**
 2180        * Returns whether this Window is active. Only a Frame or a Dialog may be
 2181        * active. The native windowing system may denote the active Window or its
 2182        * children with special decorations, such as a highlighted title bar. The
 2183        * active Window is always either the focused Window, or the first Frame or
 2184        * Dialog that is an owner of the focused Window.
 2185        *
 2186        * @return whether this is the active Window.
 2187        * @see #isFocused
 2188        * @since 1.4
 2189        */
 2190       public boolean isActive() {
 2191           return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
 2192                   getActiveWindow() == this);
 2193       }
 2194   
 2195       /**
 2196        * Returns whether this Window is focused. If there exists a focus owner,
 2197        * the focused Window is the Window that is, or contains, that focus owner.
 2198        * If there is no focus owner, then no Window is focused.
 2199        * <p>
 2200        * If the focused Window is a Frame or a Dialog it is also the active
 2201        * Window. Otherwise, the active Window is the first Frame or Dialog that
 2202        * is an owner of the focused Window.
 2203        *
 2204        * @return whether this is the focused Window.
 2205        * @see #isActive
 2206        * @since 1.4
 2207        */
 2208       public boolean isFocused() {
 2209           return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
 2210                   getGlobalFocusedWindow() == this);
 2211       }
 2212   
 2213       /**
 2214        * Gets a focus traversal key for this Window. (See <code>
 2215        * setFocusTraversalKeys</code> for a full description of each key.)
 2216        * <p>
 2217        * If the traversal key has not been explicitly set for this Window,
 2218        * then this Window's parent's traversal key is returned. If the
 2219        * traversal key has not been explicitly set for any of this Window's
 2220        * ancestors, then the current KeyboardFocusManager's default traversal key
 2221        * is returned.
 2222        *
 2223        * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
 2224        *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
 2225        *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
 2226        *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
 2227        * @return the AWTKeyStroke for the specified key
 2228        * @see Container#setFocusTraversalKeys
 2229        * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
 2230        * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
 2231        * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
 2232        * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
 2233        * @throws IllegalArgumentException if id is not one of
 2234        *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
 2235        *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
 2236        *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
 2237        *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
 2238        * @since 1.4
 2239        */
 2240       public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
 2241           if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
 2242               throw new IllegalArgumentException("invalid focus traversal key identifier");
 2243           }
 2244   
 2245           // Okay to return Set directly because it is an unmodifiable view
 2246           Set keystrokes = (focusTraversalKeys != null)
 2247               ? focusTraversalKeys[id]
 2248               : null;
 2249   
 2250           if (keystrokes != null) {
 2251               return keystrokes;
 2252           } else {
 2253               return KeyboardFocusManager.getCurrentKeyboardFocusManager().
 2254                   getDefaultFocusTraversalKeys(id);
 2255           }
 2256       }
 2257   
 2258       /**
 2259        * Does nothing because Windows must always be roots of a focus traversal
 2260        * cycle. The passed-in value is ignored.
 2261        *
 2262        * @param focusCycleRoot this value is ignored
 2263        * @see #isFocusCycleRoot
 2264        * @see Container#setFocusTraversalPolicy
 2265        * @see Container#getFocusTraversalPolicy
 2266        * @since 1.4
 2267        */
 2268       public final void setFocusCycleRoot(boolean focusCycleRoot) {
 2269       }
 2270   
 2271       /**
 2272        * Always returns <code>true</code> because all Windows must be roots of a
 2273        * focus traversal cycle.
 2274        *
 2275        * @return <code>true</code>
 2276        * @see #setFocusCycleRoot
 2277        * @see Container#setFocusTraversalPolicy
 2278        * @see Container#getFocusTraversalPolicy
 2279        * @since 1.4
 2280        */
 2281       public final boolean isFocusCycleRoot() {
 2282           return true;
 2283       }
 2284   
 2285       /**
 2286        * Always returns <code>null</code> because Windows have no ancestors; they
 2287        * represent the top of the Component hierarchy.
 2288        *
 2289        * @return <code>null</code>
 2290        * @see Container#isFocusCycleRoot()
 2291        * @since 1.4
 2292        */
 2293       public final Container getFocusCycleRootAncestor() {
 2294           return null;
 2295       }
 2296   
 2297       /**
 2298        * Returns whether this Window can become the focused Window, that is,
 2299        * whether this Window or any of its subcomponents can become the focus
 2300        * owner. For a Frame or Dialog to be focusable, its focusable Window state
 2301        * must be set to <code>true</code>. For a Window which is not a Frame or
 2302        * Dialog to be focusable, its focusable Window state must be set to
 2303        * <code>true</code>, its nearest owning Frame or Dialog must be
 2304        * showing on the screen, and it must contain at least one Component in
 2305        * its focus traversal cycle. If any of these conditions is not met, then
 2306        * neither this Window nor any of its subcomponents can become the focus
 2307        * owner.
 2308        *
 2309        * @return <code>true</code> if this Window can be the focused Window;
 2310        *         <code>false</code> otherwise
 2311        * @see #getFocusableWindowState
 2312        * @see #setFocusableWindowState
 2313        * @see #isShowing
 2314        * @see Component#isFocusable
 2315        * @since 1.4
 2316        */
 2317       public final boolean isFocusableWindow() {
 2318           // If a Window/Frame/Dialog was made non-focusable, then it is always
 2319           // non-focusable.
 2320           if (!getFocusableWindowState()) {
 2321               return false;
 2322           }
 2323   
 2324           // All other tests apply only to Windows.
 2325           if (this instanceof Frame || this instanceof Dialog) {
 2326               return true;
 2327           }
 2328   
 2329           // A Window must have at least one Component in its root focus
 2330           // traversal cycle to be focusable.
 2331           if (getFocusTraversalPolicy().getDefaultComponent(this) == null) {
 2332               return false;
 2333           }
 2334   
 2335           // A Window's nearest owning Frame or Dialog must be showing on the
 2336           // screen.
 2337           for (Window owner = getOwner(); owner != null;
 2338                owner = owner.getOwner())
 2339           {
 2340               if (owner instanceof Frame || owner instanceof Dialog) {
 2341                   return owner.isShowing();
 2342               }
 2343           }
 2344   
 2345           return false;
 2346       }
 2347   
 2348       /**
 2349        * Returns whether this Window can become the focused Window if it meets
 2350        * the other requirements outlined in <code>isFocusableWindow</code>. If
 2351        * this method returns <code>false</code>, then
 2352        * <code>isFocusableWindow</code> will return <code>false</code> as well.
 2353        * If this method retur