1 /*
2  * Copyright (c) 1995, 2020, Oracle and/or its affiliates. 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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.awt;
27 
28 import java.awt.event.ComponentEvent;
29 import java.awt.event.FocusEvent;
30 import java.awt.event.KeyEvent;
31 import java.awt.event.MouseWheelEvent;
32 import java.awt.event.WindowEvent;
33 import java.awt.event.WindowFocusListener;
34 import java.awt.event.WindowListener;
35 import java.awt.event.WindowStateListener;
36 import java.awt.geom.Path2D;
37 import java.awt.geom.Point2D;
38 import java.awt.im.InputContext;
39 import java.awt.image.BufferStrategy;
40 import java.awt.peer.ComponentPeer;
41 import java.awt.peer.WindowPeer;
42 import java.beans.PropertyChangeListener;
43 import java.io.IOException;
44 import java.io.ObjectInputStream;
45 import java.io.ObjectOutputStream;
46 import java.io.OptionalDataException;
47 import java.io.Serializable;
48 import java.lang.ref.WeakReference;
49 import java.lang.reflect.InvocationTargetException;
50 import java.security.AccessController;
51 import java.util.ArrayList;
52 import java.util.Arrays;
53 import java.util.EventListener;
54 import java.util.Locale;
55 import java.util.ResourceBundle;
56 import java.util.Set;
57 import java.util.Vector;
58 import java.util.concurrent.atomic.AtomicBoolean;
59 
60 import javax.accessibility.Accessible;
61 import javax.accessibility.AccessibleContext;
62 import javax.accessibility.AccessibleRole;
63 import javax.accessibility.AccessibleState;
64 import javax.accessibility.AccessibleStateSet;
65 
66 import sun.awt.AWTAccessor;
67 import sun.awt.AWTPermissions;
68 import sun.awt.AppContext;
69 import sun.awt.DebugSettings;
70 import sun.awt.SunToolkit;
71 import sun.awt.util.IdentityArrayList;
72 import sun.java2d.pipe.Region;
73 import sun.security.action.GetPropertyAction;
74 import sun.util.logging.PlatformLogger;
75 
76 /**
77  * A {@code Window} object is a top-level window with no borders and no
78  * menubar.
79  * The default layout for a window is {@code BorderLayout}.
80  * <p>
81  * A window must have either a frame, dialog, or another window defined as its
82  * owner when it's constructed.
83  * <p>
84  * In a multi-screen environment, you can create a {@code Window}
85  * on a different screen device by constructing the {@code Window}
86  * with {@link #Window(Window, GraphicsConfiguration)}.  The
87  * {@code GraphicsConfiguration} object is one of the
88  * {@code GraphicsConfiguration} objects of the target screen device.
89  * <p>
90  * In a virtual device multi-screen environment in which the desktop
91  * area could span multiple physical screen devices, the bounds of all
92  * configurations are relative to the virtual device coordinate system.
93  * The origin of the virtual-coordinate system is at the upper left-hand
94  * corner of the primary physical screen.  Depending on the location of
95  * the primary screen in the virtual device, negative coordinates are
96  * possible, as shown in the following figure.
97  * <p>
98  * <img src="doc-files/MultiScreen.gif"
99  * alt="Diagram shows virtual device containing 4 physical screens. Primary
100  * physical screen shows coords (0,0), other screen shows (-80,-100)."
101  * style="margin: 7px 10px;">
102  * <p>
103  * In such an environment, when calling {@code setLocation},
104  * you must pass a virtual coordinate to this method.  Similarly,
105  * calling {@code getLocationOnScreen} on a {@code Window} returns
106  * virtual device coordinates.  Call the {@code getBounds} method
107  * of a {@code GraphicsConfiguration} to find its origin in the virtual
108  * coordinate system.
109  * <p>
110  * The following code sets the location of a {@code Window}
111  * at (10, 10) relative to the origin of the physical screen
112  * of the corresponding {@code GraphicsConfiguration}.  If the
113  * bounds of the {@code GraphicsConfiguration} is not taken
114  * into account, the {@code Window} location would be set
115  * at (10, 10) relative to the virtual-coordinate system and would appear
116  * on the primary physical screen, which might be different from the
117  * physical screen of the specified {@code GraphicsConfiguration}.
118  *
119  * <pre>
120  *      Window w = new Window(Window owner, GraphicsConfiguration gc);
121  *      Rectangle bounds = gc.getBounds();
122  *      w.setLocation(10 + bounds.x, 10 + bounds.y);
123  * </pre>
124  *
125  * <p>
126  * Note: the location and size of top-level windows (including
127  * {@code Window}s, {@code Frame}s, and {@code Dialog}s)
128  * are under the control of the desktop's window management system.
129  * Calls to {@code setLocation}, {@code setSize}, and
130  * {@code setBounds} are requests (not directives) which are
131  * forwarded to the window management system.  Every effort will be
132  * made to honor such requests.  However, in some cases the window
133  * management system may ignore such requests, or modify the requested
134  * geometry in order to place and size the {@code Window} in a way
135  * that more closely matches the desktop settings.
136  * <p>
137  * Visual effects such as halos, shadows, motion effects and animations may be
138  * applied to the window by the desktop window management system. These are
139  * outside the knowledge and control of the AWT and so for the purposes of this
140  * specification are not considered part of the top-level window.
141  * <p>
142  * Due to the asynchronous nature of native event handling, the results
143  * returned by {@code getBounds}, {@code getLocation},
144  * {@code getLocationOnScreen}, and {@code getSize} might not
145  * reflect the actual geometry of the Window on screen until the last
146  * request has been processed.  During the processing of subsequent
147  * requests these values might change accordingly while the window
148  * management system fulfills the requests.
149  * <p>
150  * An application may set the size and location of an invisible
151  * {@code Window} arbitrarily, but the window management system may
152  * subsequently change its size and/or location when the
153  * {@code Window} is made visible. One or more {@code ComponentEvent}s
154  * will be generated to indicate the new geometry.
155  * <p>
156  * Windows are capable of generating the following WindowEvents:
157  * WindowOpened, WindowClosed, WindowGainedFocus, WindowLostFocus.
158  *
159  * @author      Sami Shaio
160  * @author      Arthur van Hoff
161  * @see WindowEvent
162  * @see #addWindowListener
163  * @see java.awt.BorderLayout
164  * @since       1.0
165  */
166 public class Window extends Container implements Accessible {
167 
168     /**
169      * Enumeration of available <i>window types</i>.
170      *
171      * A window type defines the generic visual appearance and behavior of a
172      * top-level window. For example, the type may affect the kind of
173      * decorations of a decorated {@code Frame} or {@code Dialog} instance.
174      * <p>
175      * Some platforms may not fully support a certain window type. Depending on
176      * the level of support, some properties of the window type may be
177      * disobeyed.
178      *
179      * @see   #getType
180      * @see   #setType
181      * @since 1.7
182      */
183     public static enum Type {
184         /**
185          * Represents a <i>normal</i> window.
186          *
187          * This is the default type for objects of the {@code Window} class or
188          * its descendants. Use this type for regular top-level windows.
189          */
190         NORMAL,
191 
192         /**
193          * Represents a <i>utility</i> window.
194          *
195          * A utility window is usually a small window such as a toolbar or a
196          * palette. The native system may render the window with smaller
197          * title-bar if the window is either a {@code Frame} or a {@code
198          * Dialog} object, and if it has its decorations enabled.
199          */
200         UTILITY,
201 
202         /**
203          * Represents a <i>popup</i> window.
204          *
205          * A popup window is a temporary window such as a drop-down menu or a
206          * tooltip. On some platforms, windows of that type may be forcibly
207          * made undecorated even if they are instances of the {@code Frame} or
208          * {@code Dialog} class, and have decorations enabled.
209          */
210         POPUP
211     }
212 
213     /**
214      * This represents the warning message that is
215      * to be displayed in a non secure window. ie :
216      * a window that has a security manager installed that denies
217      * {@code AWTPermission("showWindowWithoutWarningBanner")}.
218      * This message can be displayed anywhere in the window.
219      *
220      * @serial
221      * @see #getWarningString
222      */
223     String      warningString;
224 
225     /**
226      * {@code icons} is the graphical way we can
227      * represent the frames and dialogs.
228      * {@code Window} can't display icon but it's
229      * being inherited by owned {@code Dialog}s.
230      *
231      * @serial
232      * @see #getIconImages
233      * @see #setIconImages
234      */
235     transient java.util.List<Image> icons;
236 
237     /**
238      * Holds the reference to the component which last had focus in this window
239      * before it lost focus.
240      */
241     private transient Component temporaryLostComponent;
242 
243     static boolean systemSyncLWRequests = false;
244 
245     /**
246      * Focus transfers should be synchronous for lightweight component requests.
247      */
248     boolean syncLWRequests = false;
249     transient boolean beforeFirstShow = true;
250     private transient boolean disposing = false;
251     transient WindowDisposerRecord disposerRecord = null;
252 
253     static final int OPENED = 0x01;
254 
255     /**
256      * An Integer value representing the Window State.
257      *
258      * @serial
259      * @since 1.2
260      * @see #show
261      */
262     int state;
263 
264     /**
265      * A boolean value representing Window always-on-top state
266      * @since 1.5
267      * @serial
268      * @see #setAlwaysOnTop
269      * @see #isAlwaysOnTop
270      */
271     private boolean alwaysOnTop;
272 
273     /**
274      * Contains all the windows that have a peer object associated,
275      * i. e. between addNotify() and removeNotify() calls. The list
276      * of all Window instances can be obtained from AppContext object.
277      *
278      * @since 1.6
279      */
280     private static final IdentityArrayList<Window> allWindows = new IdentityArrayList<Window>();
281 
282     /**
283      * A vector containing all the windows this
284      * window currently owns.
285      * @since 1.2
286      * @see #getOwnedWindows
287      */
288     transient Vector<WeakReference<Window>> ownedWindowList =
289                                             new Vector<WeakReference<Window>>();
290 
291     /*
292      * We insert a weak reference into the Vector of all Windows in AppContext
293      * instead of 'this' so that garbage collection can still take place
294      * correctly.
295      */
296     private transient WeakReference<Window> weakThis;
297 
298     transient boolean showWithParent;
299 
300     /**
301      * Contains the modal dialog that blocks this window, or null
302      * if the window is unblocked.
303      *
304      * @since 1.6
305      */
306     transient Dialog modalBlocker;
307 
308     /**
309      * @serial
310      *
311      * @see java.awt.Dialog.ModalExclusionType
312      * @see #getModalExclusionType
313      * @see #setModalExclusionType
314      *
315      * @since 1.6
316      */
317     Dialog.ModalExclusionType modalExclusionType;
318 
319     transient WindowListener windowListener;
320     transient WindowStateListener windowStateListener;
321     transient WindowFocusListener windowFocusListener;
322 
323     transient InputContext inputContext;
324     private transient Object inputContextLock = new Object();
325 
326     /**
327      * Unused. Maintained for serialization backward-compatibility.
328      *
329      * @serial
330      * @since 1.2
331      */
332     private FocusManager focusMgr;
333 
334     /**
335      * Indicates whether this Window can become the focused Window.
336      *
337      * @serial
338      * @see #getFocusableWindowState
339      * @see #setFocusableWindowState
340      * @since 1.4
341      */
342     private boolean focusableWindowState = true;
343 
344     /**
345      * Indicates whether this window should receive focus on
346      * subsequently being shown (with a call to {@code setVisible(true)}), or
347      * being moved to the front (with a call to {@code toFront()}).
348      *
349      * @serial
350      * @see #setAutoRequestFocus
351      * @see #isAutoRequestFocus
352      * @since 1.7
353      */
354     private volatile boolean autoRequestFocus = true;
355 
356     /*
357      * Indicates that this window is being shown. This flag is set to true at
358      * the beginning of show() and to false at the end of show().
359      *
360      * @see #show()
361      * @see Dialog#shouldBlock
362      */
363     transient boolean isInShow = false;
364 
365     /**
366      * The opacity level of the window
367      *
368      * @serial
369      * @see #setOpacity(float)
370      * @see #getOpacity()
371      * @since 1.7
372      */
373     private volatile float opacity = 1.0f;
374 
375     /**
376      * The shape assigned to this window. This field is set to {@code null} if
377      * no shape is set (rectangular window).
378      *
379      * @serial
380      * @see #getShape()
381      * @see #setShape(Shape)
382      * @since 1.7
383      */
384     @SuppressWarnings("serial") // Not statically typed as Serializable
385     private Shape shape = null;
386 
387     private static final String base = "win";
388     private static int nameCounter = 0;
389 
390     /*
391      * JDK 1.1 serialVersionUID
392      */
393     private static final long serialVersionUID = 4497834738069338734L;
394 
395     private static final PlatformLogger log = PlatformLogger.getLogger("java.awt.Window");
396 
397     private static final boolean locationByPlatformProp;
398 
399     transient boolean isTrayIconWindow = false;
400 
401     /**
402      * These fields are initialized in the native peer code
403      * or via AWTAccessor's WindowAccessor.
404      */
405     private transient volatile int securityWarningWidth = 0;
406     private transient volatile int securityWarningHeight = 0;
407 
408     static {
409         /* ensure that the necessary native libraries are loaded */
Toolkit.loadLibraries()410         Toolkit.loadLibraries();
411         if (!GraphicsEnvironment.isHeadless()) {
initIDs()412             initIDs();
413         }
414 
415         String s = java.security.AccessController.doPrivileged(
416             new GetPropertyAction("java.awt.syncLWRequests"));
417         systemSyncLWRequests = (s != null && s.equals("true"));
418         s = java.security.AccessController.doPrivileged(
419             new GetPropertyAction("java.awt.Window.locationByPlatform"));
420         locationByPlatformProp = (s != null && s.equals("true"));
421     }
422 
423     /**
424      * Initialize JNI field and method IDs for fields that may be
425        accessed from C.
426      */
initIDs()427     private static native void initIDs();
428 
429     /**
430      * Constructs a new, initially invisible window in default size with the
431      * specified {@code GraphicsConfiguration}.
432      * <p>
433      * If there is a security manager, then it is invoked to check
434      * {@code AWTPermission("showWindowWithoutWarningBanner")}
435      * to determine whether or not the window must be displayed with
436      * a warning banner.
437      *
438      * @param gc the {@code GraphicsConfiguration} of the target screen
439      *     device. If {@code gc} is {@code null}, the system default
440      *     {@code GraphicsConfiguration} is assumed
441      * @exception IllegalArgumentException if {@code gc}
442      *    is not from a screen device
443      * @exception HeadlessException when
444      *     {@code GraphicsEnvironment.isHeadless()} returns {@code true}
445      *
446      * @see java.awt.GraphicsEnvironment#isHeadless
447      */
Window(GraphicsConfiguration gc)448     Window(GraphicsConfiguration gc) {
449         init(gc);
450     }
451 
452     transient Object anchor = new Object();
453     static class WindowDisposerRecord implements sun.java2d.DisposerRecord {
454         WeakReference<Window> owner;
455         final WeakReference<Window> weakThis;
456         final WeakReference<AppContext> context;
457 
WindowDisposerRecord(AppContext context, Window victim)458         WindowDisposerRecord(AppContext context, Window victim) {
459             weakThis = victim.weakThis;
460             this.context = new WeakReference<AppContext>(context);
461         }
462 
updateOwner()463         public void updateOwner() {
464             Window victim = weakThis.get();
465             owner = (victim == null)
466                     ? null
467                     : new WeakReference<Window>(victim.getOwner());
468         }
469 
dispose()470         public void dispose() {
471             if (owner != null) {
472                 Window parent = owner.get();
473                 if (parent != null) {
474                     parent.removeOwnedWindow(weakThis);
475                 }
476             }
477             AppContext ac = context.get();
478             if (null != ac) {
479                 Window.removeFromWindowList(ac, weakThis);
480             }
481         }
482     }
483 
initGC(GraphicsConfiguration gc)484     private GraphicsConfiguration initGC(GraphicsConfiguration gc) {
485         GraphicsEnvironment.checkHeadless();
486 
487         if (gc == null) {
488             gc = GraphicsEnvironment.getLocalGraphicsEnvironment().
489                 getDefaultScreenDevice().getDefaultConfiguration();
490         }
491         setGraphicsConfiguration(gc);
492 
493         return gc;
494     }
495 
init(GraphicsConfiguration gc)496     private void init(GraphicsConfiguration gc) {
497         GraphicsEnvironment.checkHeadless();
498 
499         syncLWRequests = systemSyncLWRequests;
500 
501         weakThis = new WeakReference<Window>(this);
502         addToWindowList();
503 
504         setWarningString();
505         this.cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
506         this.visible = false;
507 
508         gc = initGC(gc);
509 
510         if (gc.getDevice().getType() !=
511             GraphicsDevice.TYPE_RASTER_SCREEN) {
512             throw new IllegalArgumentException("not a screen device");
513         }
514         setLayout(new BorderLayout());
515 
516         /* offset the initial location with the original of the screen */
517         /* and any insets                                              */
518         Rectangle screenBounds = gc.getBounds();
519         Insets screenInsets = getToolkit().getScreenInsets(gc);
520         int x = getX() + screenBounds.x + screenInsets.left;
521         int y = getY() + screenBounds.y + screenInsets.top;
522         if (x != this.x || y != this.y) {
523             setLocation(x, y);
524             /* reset after setLocation */
525             setLocationByPlatform(locationByPlatformProp);
526         }
527 
528         modalExclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
529         disposerRecord = new WindowDisposerRecord(appContext, this);
530         sun.java2d.Disposer.addRecord(anchor, disposerRecord);
531 
532         SunToolkit.checkAndSetPolicy(this);
533     }
534 
535     /**
536      * Constructs a new, initially invisible window in the default size.
537      * <p>
538      * If there is a security manager set, it is invoked to check
539      * {@code AWTPermission("showWindowWithoutWarningBanner")}.
540      * If that check fails with a {@code SecurityException} then a warning
541      * banner is created.
542      *
543      * @exception HeadlessException when
544      *     {@code GraphicsEnvironment.isHeadless()} returns {@code true}
545      *
546      * @see java.awt.GraphicsEnvironment#isHeadless
547      */
Window()548     Window() throws HeadlessException {
549         GraphicsEnvironment.checkHeadless();
550         init((GraphicsConfiguration)null);
551     }
552 
553     /**
554      * Constructs a new, initially invisible window with the specified
555      * {@code Frame} as its owner. The window will not be focusable
556      * unless its owner is showing on the screen.
557      * <p>
558      * If there is a security manager set, it is invoked to check
559      * {@code AWTPermission("showWindowWithoutWarningBanner")}.
560      * If that check fails with a {@code SecurityException} then a warning
561      * banner is created.
562      *
563      * @param owner the {@code Frame} to act as owner or {@code null}
564      *    if this window has no owner
565      * @exception IllegalArgumentException if the {@code owner}'s
566      *    {@code GraphicsConfiguration} is not from a screen device
567      * @exception HeadlessException when
568      *    {@code GraphicsEnvironment.isHeadless} returns {@code true}
569      *
570      * @see java.awt.GraphicsEnvironment#isHeadless
571      * @see #isShowing
572      */
Window(Frame owner)573     public Window(Frame owner) {
574         this(owner == null ? (GraphicsConfiguration)null :
575             owner.getGraphicsConfiguration());
576         ownedInit(owner);
577     }
578 
579     /**
580      * Constructs a new, initially invisible window with the specified
581      * {@code Window} as its owner. This window will not be focusable
582      * unless its nearest owning {@code Frame} or {@code Dialog}
583      * is showing on the screen.
584      * <p>
585      * If there is a security manager set, it is invoked to check
586      * {@code AWTPermission("showWindowWithoutWarningBanner")}.
587      * If that check fails with a {@code SecurityException} then a
588      * warning banner is created.
589      *
590      * @param owner the {@code Window} to act as owner or
591      *     {@code null} if this window has no owner
592      * @exception IllegalArgumentException if the {@code owner}'s
593      *     {@code GraphicsConfiguration} is not from a screen device
594      * @exception HeadlessException when
595      *     {@code GraphicsEnvironment.isHeadless()} returns
596      *     {@code true}
597      *
598      * @see       java.awt.GraphicsEnvironment#isHeadless
599      * @see       #isShowing
600      *
601      * @since     1.2
602      */
Window(Window owner)603     public Window(Window owner) {
604         this(owner == null ? (GraphicsConfiguration)null :
605             owner.getGraphicsConfiguration());
606         ownedInit(owner);
607     }
608 
609     /**
610      * Constructs a new, initially invisible window with the specified owner
611      * {@code Window} and a {@code GraphicsConfiguration}
612      * of a screen device. The Window will not be focusable unless
613      * its nearest owning {@code Frame} or {@code Dialog}
614      * is showing on the screen.
615      * <p>
616      * If there is a security manager set, it is invoked to check
617      * {@code AWTPermission("showWindowWithoutWarningBanner")}. If that
618      * check fails with a {@code SecurityException} then a warning banner
619      * is created.
620      *
621      * @param owner the window to act as owner or {@code null}
622      *     if this window has no owner
623      * @param gc the {@code GraphicsConfiguration} of the target
624      *     screen device; if {@code gc} is {@code null},
625      *     the system default {@code GraphicsConfiguration} is assumed
626      * @exception IllegalArgumentException if {@code gc}
627      *     is not from a screen device
628      * @exception HeadlessException when
629      *     {@code GraphicsEnvironment.isHeadless()} returns
630      *     {@code true}
631      *
632      * @see       java.awt.GraphicsEnvironment#isHeadless
633      * @see       GraphicsConfiguration#getBounds
634      * @see       #isShowing
635      * @since     1.3
636      */
Window(Window owner, GraphicsConfiguration gc)637     public Window(Window owner, GraphicsConfiguration gc) {
638         this(gc);
639         ownedInit(owner);
640     }
641 
ownedInit(Window owner)642     private void ownedInit(Window owner) {
643         this.parent = owner;
644         if (owner != null) {
645             owner.addOwnedWindow(weakThis);
646             if (owner.isAlwaysOnTop()) {
647                 try {
648                     setAlwaysOnTop(true);
649                 } catch (SecurityException ignore) {
650                 }
651             }
652         }
653 
654         // WindowDisposerRecord requires a proper value of parent field.
655         disposerRecord.updateOwner();
656     }
657 
658     /**
659      * Construct a name for this component.  Called by getName() when the
660      * name is null.
661      */
constructComponentName()662     String constructComponentName() {
663         synchronized (Window.class) {
664             return base + nameCounter++;
665         }
666     }
667 
668     /**
669      * Returns the sequence of images to be displayed as the icon for this window.
670      * <p>
671      * This method returns a copy of the internally stored list, so all operations
672      * on the returned object will not affect the window's behavior.
673      *
674      * @return    the copy of icon images' list for this window, or
675      *            empty list if this window doesn't have icon images.
676      * @see       #setIconImages
677      * @see       #setIconImage(Image)
678      * @since     1.6
679      */
getIconImages()680     public java.util.List<Image> getIconImages() {
681         java.util.List<Image> icons = this.icons;
682         if (icons == null || icons.size() == 0) {
683             return new ArrayList<Image>();
684         }
685         return new ArrayList<Image>(icons);
686     }
687 
688     /**
689      * Sets the sequence of images to be displayed as the icon
690      * for this window. Subsequent calls to {@code getIconImages} will
691      * always return a copy of the {@code icons} list.
692      * <p>
693      * Depending on the platform capabilities one or several images
694      * of different dimensions will be used as the window's icon.
695      * <p>
696      * The {@code icons} list can contain {@code MultiResolutionImage} images also.
697      * Suitable image depending on screen resolution is extracted from
698      * base {@code MultiResolutionImage} image and added to the icons list
699      * while base resolution image is removed from list.
700      * The {@code icons} list is scanned for the images of most
701      * appropriate dimensions from the beginning. If the list contains
702      * several images of the same size, the first will be used.
703      * <p>
704      * Ownerless windows with no icon specified use platform-default icon.
705      * The icon of an owned window may be inherited from the owner
706      * unless explicitly overridden.
707      * Setting the icon to {@code null} or empty list restores
708      * the default behavior.
709      * <p>
710      * Note : Native windowing systems may use different images of differing
711      * dimensions to represent a window, depending on the context (e.g.
712      * window decoration, window list, taskbar, etc.). They could also use
713      * just a single image for all contexts or no image at all.
714      *
715      * @param     icons the list of icon images to be displayed.
716      * @see       #getIconImages()
717      * @see       #setIconImage(Image)
718      * @since     1.6
719      */
setIconImages(java.util.List<? extends Image> icons)720     public synchronized void setIconImages(java.util.List<? extends Image> icons) {
721         this.icons = (icons == null) ? new ArrayList<Image>() :
722             new ArrayList<Image>(icons);
723         WindowPeer peer = (WindowPeer)this.peer;
724         if (peer != null) {
725             peer.updateIconImages();
726         }
727         // Always send a property change event
728         firePropertyChange("iconImage", null, null);
729     }
730 
731     /**
732      * Sets the image to be displayed as the icon for this window.
733      * <p>
734      * This method can be used instead of {@link #setIconImages setIconImages()}
735      * to specify a single image as a window's icon.
736      * <p>
737      * The following statement:
738      * <pre>
739      *     setIconImage(image);
740      * </pre>
741      * is equivalent to:
742      * <pre>
743      *     ArrayList&lt;Image&gt; imageList = new ArrayList&lt;Image&gt;();
744      *     imageList.add(image);
745      *     setIconImages(imageList);
746      * </pre>
747      * <p>
748      * Note : Native windowing systems may use different images of differing
749      * dimensions to represent a window, depending on the context (e.g.
750      * window decoration, window list, taskbar, etc.). They could also use
751      * just a single image for all contexts or no image at all.
752      *
753      * @param     image the icon image to be displayed.
754      * @see       #setIconImages
755      * @see       #getIconImages()
756      * @since     1.6
757      */
setIconImage(Image image)758     public void setIconImage(Image image) {
759         ArrayList<Image> imageList = new ArrayList<Image>();
760         if (image != null) {
761             imageList.add(image);
762         }
763         setIconImages(imageList);
764     }
765 
766     /**
767      * Makes this Window displayable by creating the connection to its
768      * native screen resource.
769      * This method is called internally by the toolkit and should
770      * not be called directly by programs.
771      * @see Component#isDisplayable
772      * @see Container#removeNotify
773      * @since 1.0
774      */
addNotify()775     public void addNotify() {
776         synchronized (getTreeLock()) {
777             Container parent = this.parent;
778             if (parent != null && parent.peer == null) {
779                 parent.addNotify();
780             }
781             if (peer == null) {
782                 peer = getComponentFactory().createWindow(this);
783             }
784             synchronized (allWindows) {
785                 allWindows.add(this);
786             }
787             super.addNotify();
788         }
789     }
790 
791     /**
792      * {@inheritDoc}
793      */
removeNotify()794     public void removeNotify() {
795         synchronized (getTreeLock()) {
796             synchronized (allWindows) {
797                 allWindows.remove(this);
798             }
799             super.removeNotify();
800         }
801     }
802 
803     /**
804      * Causes this Window to be sized to fit the preferred size
805      * and layouts of its subcomponents. The resulting width and
806      * height of the window are automatically enlarged if either
807      * of dimensions is less than the minimum size as specified
808      * by the previous call to the {@code setMinimumSize} method.
809      * <p>
810      * If the window and/or its owner are not displayable yet,
811      * both of them are made displayable before calculating
812      * the preferred size. The Window is validated after its
813      * size is being calculated.
814      *
815      * @see Component#isDisplayable
816      * @see #setMinimumSize
817      */
818     @SuppressWarnings("deprecation")
pack()819     public void pack() {
820         Container parent = this.parent;
821         if (parent != null && parent.peer == null) {
822             parent.addNotify();
823         }
824         if (peer == null) {
825             addNotify();
826         }
827         Dimension newSize = getPreferredSize();
828         if (peer != null) {
829             setClientSize(newSize.width, newSize.height);
830         }
831 
832         if(beforeFirstShow) {
833             isPacked = true;
834         }
835 
836         validateUnconditionally();
837     }
838 
839     /**
840      * Sets the minimum size of this window to a constant
841      * value.  Subsequent calls to {@code getMinimumSize}
842      * will always return this value. If current window's
843      * size is less than {@code minimumSize} the size of the
844      * window is automatically enlarged to honor the minimum size.
845      * <p>
846      * If the {@code setSize} or {@code setBounds} methods
847      * are called afterwards with a width or height less than
848      * that was specified by the {@code setMinimumSize} method
849      * the window is automatically enlarged to meet
850      * the {@code minimumSize} value. The {@code minimumSize}
851      * value also affects the behaviour of the {@code pack} method.
852      * <p>
853      * The default behavior is restored by setting the minimum size
854      * parameter to the {@code null} value.
855      * <p>
856      * Resizing operation may be restricted if the user tries
857      * to resize window below the {@code minimumSize} value.
858      * This behaviour is platform-dependent.
859      *
860      * @param minimumSize the new minimum size of this window
861      * @see Component#setMinimumSize
862      * @see #getMinimumSize
863      * @see #isMinimumSizeSet
864      * @see #setSize(Dimension)
865      * @see #pack
866      * @since 1.6
867      */
setMinimumSize(Dimension minimumSize)868     public void setMinimumSize(Dimension minimumSize) {
869         synchronized (getTreeLock()) {
870             super.setMinimumSize(minimumSize);
871             Dimension size = getSize();
872             if (isMinimumSizeSet()) {
873                 if (size.width < minimumSize.width || size.height < minimumSize.height) {
874                     int nw = Math.max(width, minimumSize.width);
875                     int nh = Math.max(height, minimumSize.height);
876                     setSize(nw, nh);
877                 }
878             }
879             if (peer != null) {
880                 ((WindowPeer)peer).updateMinimumSize();
881             }
882         }
883     }
884 
885     /**
886      * {@inheritDoc}
887      * <p>
888      * The {@code d.width} and {@code d.height} values
889      * are automatically enlarged if either is less than
890      * the minimum size as specified by previous call to
891      * {@code setMinimumSize}.
892      * <p>
893      * The method changes the geometry-related data. Therefore,
894      * the native windowing system may ignore such requests, or it may modify
895      * the requested data, so that the {@code Window} object is placed and sized
896      * in a way that corresponds closely to the desktop settings.
897      *
898      * @see #getSize
899      * @see #setBounds
900      * @see #setMinimumSize
901      * @since 1.6
902      */
setSize(Dimension d)903     public void setSize(Dimension d) {
904         super.setSize(d);
905     }
906 
907     /**
908      * {@inheritDoc}
909      * <p>
910      * The {@code width} and {@code height} values
911      * are automatically enlarged if either is less than
912      * the minimum size as specified by previous call to
913      * {@code setMinimumSize}.
914      * <p>
915      * The method changes the geometry-related data. Therefore,
916      * the native windowing system may ignore such requests, or it may modify
917      * the requested data, so that the {@code Window} object is placed and sized
918      * in a way that corresponds closely to the desktop settings.
919      *
920      * @see #getSize
921      * @see #setBounds
922      * @see #setMinimumSize
923      * @since 1.6
924      */
setSize(int width, int height)925     public void setSize(int width, int height) {
926         super.setSize(width, height);
927     }
928 
929     /**
930      * {@inheritDoc}
931      * <p>
932      * The method changes the geometry-related data. Therefore,
933      * the native windowing system may ignore such requests, or it may modify
934      * the requested data, so that the {@code Window} object is placed and sized
935      * in a way that corresponds closely to the desktop settings.
936      */
937     @Override
setLocation(int x, int y)938     public void setLocation(int x, int y) {
939         super.setLocation(x, y);
940     }
941 
942     /**
943      * {@inheritDoc}
944      * <p>
945      * The method changes the geometry-related data. Therefore,
946      * the native windowing system may ignore such requests, or it may modify
947      * the requested data, so that the {@code Window} object is placed and sized
948      * in a way that corresponds closely to the desktop settings.
949      */
950     @Override
setLocation(Point p)951     public void setLocation(Point p) {
952         super.setLocation(p);
953     }
954 
955     /**
956      * @deprecated As of JDK version 1.1,
957      * replaced by {@code setBounds(int, int, int, int)}.
958      */
959     @Deprecated
reshape(int x, int y, int width, int height)960     public void reshape(int x, int y, int width, int height) {
961         if (isMinimumSizeSet()) {
962             Dimension minSize = getMinimumSize();
963             if (width < minSize.width) {
964                 width = minSize.width;
965             }
966             if (height < minSize.height) {
967                 height = minSize.height;
968             }
969         }
970         super.reshape(x, y, width, height);
971     }
972 
setClientSize(int w, int h)973     void setClientSize(int w, int h) {
974         synchronized (getTreeLock()) {
975             setBoundsOp(ComponentPeer.SET_CLIENT_SIZE);
976             setBounds(x, y, w, h);
977         }
978     }
979 
980     private static final AtomicBoolean
981         beforeFirstWindowShown = new AtomicBoolean(true);
982 
closeSplashScreen()983     final void closeSplashScreen() {
984         if (isTrayIconWindow) {
985             return;
986         }
987         if (beforeFirstWindowShown.getAndSet(false)) {
988             // We don't use SplashScreen.getSplashScreen() to avoid instantiating
989             // the object if it hasn't been requested by user code explicitly
990             SunToolkit.closeSplashScreen();
991             SplashScreen.markClosed();
992         }
993     }
994 
995     /**
996      * Shows or hides this {@code Window} depending on the value of parameter
997      * {@code b}.
998      * <p>
999      * If the method shows the window then the window is also made
1000      * focused under the following conditions:
1001      * <ul>
1002      * <li> The {@code Window} meets the requirements outlined in the
1003      *      {@link #isFocusableWindow} method.
1004      * <li> The {@code Window}'s {@code autoRequestFocus} property is of the {@code true} value.
1005      * <li> Native windowing system allows the {@code Window} to get focused.
1006      * </ul>
1007      * There is an exception for the second condition (the value of the
1008      * {@code autoRequestFocus} property). The property is not taken into account if the
1009      * window is a modal dialog, which blocks the currently focused window.
1010      * <p>
1011      * Developers must never assume that the window is the focused or active window
1012      * until it receives a WINDOW_GAINED_FOCUS or WINDOW_ACTIVATED event.
1013      * @param b  if {@code true}, makes the {@code Window} visible,
1014      * otherwise hides the {@code Window}.
1015      * If the {@code Window} and/or its owner
1016      * are not yet displayable, both are made displayable.  The
1017      * {@code Window} will be validated prior to being made visible.
1018      * If the {@code Window} is already visible, this will bring the
1019      * {@code Window} to the front.<p>
1020      * If {@code false}, hides this {@code Window}, its subcomponents, and all
1021      * of its owned children.
1022      * The {@code Window} and its subcomponents can be made visible again
1023      * with a call to {@code #setVisible(true)}.
1024      * @see java.awt.Component#isDisplayable
1025      * @see java.awt.Component#setVisible
1026      * @see java.awt.Window#toFront
1027      * @see java.awt.Window#dispose
1028      * @see java.awt.Window#setAutoRequestFocus
1029      * @see java.awt.Window#isFocusableWindow
1030      */
setVisible(boolean b)1031     public void setVisible(boolean b) {
1032         super.setVisible(b);
1033     }
1034 
1035     /**
1036      * Makes the Window visible. If the Window and/or its owner
1037      * are not yet displayable, both are made displayable.  The
1038      * Window will be validated prior to being made visible.
1039      * If the Window is already visible, this will bring the Window
1040      * to the front.
1041      * @see       Component#isDisplayable
1042      * @see       #toFront
1043      * @deprecated As of JDK version 1.5, replaced by
1044      * {@link #setVisible(boolean)}.
1045      */
1046     @Deprecated
show()1047     public void show() {
1048         if (peer == null) {
1049             addNotify();
1050         }
1051         validateUnconditionally();
1052 
1053         isInShow = true;
1054         if (visible) {
1055             toFront();
1056         } else {
1057             beforeFirstShow = false;
1058             closeSplashScreen();
1059             Dialog.checkShouldBeBlocked(this);
1060             super.show();
1061             locationByPlatform = false;
1062             for (int i = 0; i < ownedWindowList.size(); i++) {
1063                 Window child = ownedWindowList.elementAt(i).get();
1064                 if ((child != null) && child.showWithParent) {
1065                     child.show();
1066                     child.showWithParent = false;
1067                 }       // endif
1068             }   // endfor
1069             if (!isModalBlocked()) {
1070                 updateChildrenBlocking();
1071             } else {
1072                 // fix for 6532736: after this window is shown, its blocker
1073                 // should be raised to front
1074                 modalBlocker.toFront_NoClientCode();
1075             }
1076             if (this instanceof Frame || this instanceof Dialog) {
1077                 updateChildFocusableWindowState(this);
1078             }
1079         }
1080         isInShow = false;
1081 
1082         // If first time shown, generate WindowOpened event
1083         if ((state & OPENED) == 0) {
1084             postWindowEvent(WindowEvent.WINDOW_OPENED);
1085             state |= OPENED;
1086         }
1087     }
1088 
updateChildFocusableWindowState(Window w)1089     static void updateChildFocusableWindowState(Window w) {
1090         if (w.peer != null && w.isShowing()) {
1091             ((WindowPeer)w.peer).updateFocusableWindowState();
1092         }
1093         for (int i = 0; i < w.ownedWindowList.size(); i++) {
1094             Window child = w.ownedWindowList.elementAt(i).get();
1095             if (child != null) {
1096                 updateChildFocusableWindowState(child);
1097             }
1098         }
1099     }
1100 
postWindowEvent(int id)1101     synchronized void postWindowEvent(int id) {
1102         if (windowListener != null
1103             || (eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0
1104             ||  Toolkit.enabledOnToolkit(AWTEvent.WINDOW_EVENT_MASK)) {
1105             WindowEvent e = new WindowEvent(this, id);
1106             Toolkit.getEventQueue().postEvent(e);
1107         }
1108     }
1109 
1110     /**
1111      * Hide this Window, its subcomponents, and all of its owned children.
1112      * The Window and its subcomponents can be made visible again
1113      * with a call to {@code show}.
1114      * @see #show
1115      * @see #dispose
1116      * @deprecated As of JDK version 1.5, replaced by
1117      * {@link #setVisible(boolean)}.
1118      */
1119     @Deprecated
hide()1120     public void hide() {
1121         synchronized(ownedWindowList) {
1122             for (int i = 0; i < ownedWindowList.size(); i++) {
1123                 Window child = ownedWindowList.elementAt(i).get();
1124                 if ((child != null) && child.visible) {
1125                     child.hide();
1126                     child.showWithParent = true;
1127                 }
1128             }
1129         }
1130         if (isModalBlocked()) {
1131             modalBlocker.unblockWindow(this);
1132         }
1133         super.hide();
1134         locationByPlatform = false;
1135     }
1136 
clearMostRecentFocusOwnerOnHide()1137     final void clearMostRecentFocusOwnerOnHide() {
1138         /* do nothing */
1139     }
1140 
1141     /**
1142      * Releases all of the native screen resources used by this
1143      * {@code Window}, its subcomponents, and all of its owned
1144      * children. That is, the resources for these {@code Component}s
1145      * will be destroyed, any memory they consume will be returned to the
1146      * OS, and they will be marked as undisplayable.
1147      * <p>
1148      * The {@code Window} and its subcomponents can be made displayable
1149      * again by rebuilding the native resources with a subsequent call to
1150      * {@code pack} or {@code show}. The states of the recreated
1151      * {@code Window} and its subcomponents will be identical to the
1152      * states of these objects at the point where the {@code Window}
1153      * was disposed (not accounting for additional modifications between
1154      * those actions).
1155      * <p>
1156      * <b>Note</b>: When the last displayable window
1157      * within the Java virtual machine (VM) is disposed of, the VM may
1158      * terminate.  See <a href="doc-files/AWTThreadIssues.html#Autoshutdown">
1159      * AWT Threading Issues</a> for more information.
1160      * @see Component#isDisplayable
1161      * @see #pack
1162      * @see #show
1163      */
dispose()1164     public void dispose() {
1165         doDispose();
1166     }
1167 
1168     /*
1169      * Fix for 4872170.
1170      * If dispose() is called on parent then its children have to be disposed as well
1171      * as reported in javadoc. So we need to implement this functionality even if a
1172      * child overrides dispose() in a wrong way without calling super.dispose().
1173      */
disposeImpl()1174     void disposeImpl() {
1175         dispose();
1176         if (peer != null) {
1177             doDispose();
1178         }
1179     }
1180 
doDispose()1181     void doDispose() {
1182     class DisposeAction implements Runnable {
1183         public void run() {
1184             disposing = true;
1185             try {
1186                 // Check if this window is the fullscreen window for the
1187                 // device. Exit the fullscreen mode prior to disposing
1188                 // of the window if that's the case.
1189                 GraphicsDevice gd = getGraphicsConfiguration().getDevice();
1190                 if (gd.getFullScreenWindow() == Window.this) {
1191                     gd.setFullScreenWindow(null);
1192                 }
1193 
1194                 Object[] ownedWindowArray;
1195                 synchronized(ownedWindowList) {
1196                     ownedWindowArray = new Object[ownedWindowList.size()];
1197                     ownedWindowList.copyInto(ownedWindowArray);
1198                 }
1199                 for (int i = 0; i < ownedWindowArray.length; i++) {
1200                     Window child = (Window) (((WeakReference)
1201                                    (ownedWindowArray[i])).get());
1202                     if (child != null) {
1203                         child.disposeImpl();
1204                     }
1205                 }
1206                 hide();
1207                 beforeFirstShow = true;
1208                 removeNotify();
1209                 synchronized (inputContextLock) {
1210                     if (inputContext != null) {
1211                         inputContext.dispose();
1212                         inputContext = null;
1213                     }
1214                 }
1215                 clearCurrentFocusCycleRootOnHide();
1216             } finally {
1217                 disposing = false;
1218             }
1219         }
1220     }
1221         boolean fireWindowClosedEvent = isDisplayable();
1222         DisposeAction action = new DisposeAction();
1223         if (EventQueue.isDispatchThread()) {
1224             action.run();
1225         }
1226         else {
1227             try {
1228                 EventQueue.invokeAndWait(this, action);
1229             }
1230             catch (InterruptedException e) {
1231                 System.err.println("Disposal was interrupted:");
1232                 e.printStackTrace();
1233             }
1234             catch (InvocationTargetException e) {
1235                 System.err.println("Exception during disposal:");
1236                 e.printStackTrace();
1237             }
1238         }
1239         // Execute outside the Runnable because postWindowEvent is
1240         // synchronized on (this). We don't need to synchronize the call
1241         // on the EventQueue anyways.
1242         if (fireWindowClosedEvent) {
1243             postWindowEvent(WindowEvent.WINDOW_CLOSED);
1244         }
1245     }
1246 
1247     /*
1248      * Should only be called while holding the tree lock.
1249      * It's overridden here because parent == owner in Window,
1250      * and we shouldn't adjust counter on owner
1251      */
adjustListeningChildrenOnParent(long mask, int num)1252     void adjustListeningChildrenOnParent(long mask, int num) {
1253     }
1254 
1255     // Should only be called while holding tree lock
adjustDescendantsOnParent(int num)1256     void adjustDescendantsOnParent(int num) {
1257         // do nothing since parent == owner and we shouldn't
1258         // adjust counter on owner
1259     }
1260 
1261     /**
1262      * If this Window is visible, brings this Window to the front and may make
1263      * it the focused Window.
1264      * <p>
1265      * Places this Window at the top of the stacking order and shows it in
1266      * front of any other Windows in this VM. No action will take place if this
1267      * Window is not visible. Some platforms do not allow Windows which own
1268      * other Windows to appear on top of those owned Windows. Some platforms
1269      * may not permit this VM to place its Windows above windows of native
1270      * applications, or Windows of other VMs. This permission may depend on
1271      * whether a Window in this VM is already focused. Every attempt will be
1272      * made to move this Window as high as possible in the stacking order;
1273      * however, developers should not assume that this method will move this
1274      * Window above all other windows in every situation.
1275      * <p>
1276      * Developers must never assume that this Window is the focused or active
1277      * Window until this Window receives a WINDOW_GAINED_FOCUS or WINDOW_ACTIVATED
1278      * event. On platforms where the top-most window is the focused window, this
1279      * method will <b>probably</b> focus this Window (if it is not already focused)
1280      * under the following conditions:
1281      * <ul>
1282      * <li> The window meets the requirements outlined in the
1283      *      {@link #isFocusableWindow} method.
1284      * <li> The window's property {@code autoRequestFocus} is of the
1285      *      {@code true} value.
1286      * <li> Native windowing system allows the window to get focused.
1287      * </ul>
1288      * On platforms where the stacking order does not typically affect the focused
1289      * window, this method will <b>probably</b> leave the focused and active
1290      * Windows unchanged.
1291      * <p>
1292      * If this method causes this Window to be focused, and this Window is a
1293      * Frame or a Dialog, it will also become activated. If this Window is
1294      * focused, but it is not a Frame or a Dialog, then the first Frame or
1295      * Dialog that is an owner of this Window will be activated.
1296      * <p>
1297      * If this window is blocked by modal dialog, then the blocking dialog
1298      * is brought to the front and remains above the blocked window.
1299      *
1300      * @see       #toBack
1301      * @see       #setAutoRequestFocus
1302      * @see       #isFocusableWindow
1303      */
toFront()1304     public void toFront() {
1305         toFront_NoClientCode();
1306     }
1307 
1308     // This functionality is implemented in a final package-private method
1309     // to insure that it cannot be overridden by client subclasses.
toFront_NoClientCode()1310     final void toFront_NoClientCode() {
1311         if (visible) {
1312             WindowPeer peer = (WindowPeer)this.peer;
1313             if (peer != null) {
1314                 peer.toFront();
1315             }
1316             if (isModalBlocked()) {
1317                 modalBlocker.toFront_NoClientCode();
1318             }
1319         }
1320     }
1321 
1322     /**
1323      * If this Window is visible, sends this Window to the back and may cause
1324      * it to lose focus or activation if it is the focused or active Window.
1325      * <p>
1326      * Places this Window at the bottom of the stacking order and shows it
1327      * behind any other Windows in this VM. No action will take place is this
1328      * Window is not visible. Some platforms do not allow Windows which are
1329      * owned by other Windows to appear below their owners. Every attempt will
1330      * be made to move this Window as low as possible in the stacking order;
1331      * however, developers should not assume that this method will move this
1332      * Window below all other windows in every situation.
1333      * <p>
1334      * Because of variations in native windowing systems, no guarantees about
1335      * changes to the focused and active Windows can be made. Developers must
1336      * never assume that this Window is no longer the focused or active Window
1337      * until this Window receives a WINDOW_LOST_FOCUS or WINDOW_DEACTIVATED
1338      * event. On platforms where the top-most window is the focused window,
1339      * this method will <b>probably</b> cause this Window to lose focus. In
1340      * that case, the next highest, focusable Window in this VM will receive
1341      * focus. On platforms where the stacking order does not typically affect
1342      * the focused window, this method will <b>probably</b> leave the focused
1343      * and active Windows unchanged.
1344      *
1345      * @see       #toFront
1346      */
toBack()1347     public void toBack() {
1348         toBack_NoClientCode();
1349     }
1350 
1351     // This functionality is implemented in a final package-private method
1352     // to insure that it cannot be overridden by client subclasses.
toBack_NoClientCode()1353     final void toBack_NoClientCode() {
1354         if(isAlwaysOnTop()) {
1355             try {
1356                 setAlwaysOnTop(false);
1357             }catch(SecurityException e) {
1358             }
1359         }
1360         if (visible) {
1361             WindowPeer peer = (WindowPeer)this.peer;
1362             if (peer != null) {
1363                 peer.toBack();
1364             }
1365         }
1366     }
1367 
1368     /**
1369      * Returns the toolkit of this frame.
1370      * @return    the toolkit of this window.
1371      * @see       Toolkit
1372      * @see       Toolkit#getDefaultToolkit
1373      * @see       Component#getToolkit
1374      */
getToolkit()1375     public Toolkit getToolkit() {
1376         return Toolkit.getDefaultToolkit();
1377     }
1378 
1379     /**
1380      * Gets the warning string that is displayed with this window.
1381      * If this window is insecure, the warning string is displayed
1382      * somewhere in the visible area of the window. A window is
1383      * insecure if there is a security manager and the security
1384      * manager denies
1385      * {@code AWTPermission("showWindowWithoutWarningBanner")}.
1386      * <p>
1387      * If the window is secure, then {@code getWarningString}
1388      * returns {@code null}. If the window is insecure, this
1389      * method checks for the system property
1390      * {@code awt.appletWarning}
1391      * and returns the string value of that property.
1392      * @return    the warning string for this window.
1393      */
getWarningString()1394     public final String getWarningString() {
1395         return warningString;
1396     }
1397 
setWarningString()1398     private void setWarningString() {
1399         warningString = null;
1400         SecurityManager sm = System.getSecurityManager();
1401         if (sm != null) {
1402             try {
1403                 sm.checkPermission(AWTPermissions.TOPLEVEL_WINDOW_PERMISSION);
1404             } catch (SecurityException se) {
1405                 // make sure the privileged action is only
1406                 // for getting the property! We don't want the
1407                 // above checkPermission call to always succeed!
1408                 warningString = AccessController.doPrivileged(
1409                       new GetPropertyAction("awt.appletWarning",
1410                                             "Java Applet Window"));
1411             }
1412         }
1413     }
1414 
1415     /**
1416      * Gets the {@code Locale} object that is associated
1417      * with this window, if the locale has been set.
1418      * If no locale has been set, then the default locale
1419      * is returned.
1420      * @return    the locale that is set for this window.
1421      * @see       java.util.Locale
1422      * @since     1.1
1423      */
getLocale()1424     public Locale getLocale() {
1425       if (this.locale == null) {
1426         return Locale.getDefault();
1427       }
1428       return this.locale;
1429     }
1430 
1431     /**
1432      * Gets the input context for this window. A window always has an input context,
1433      * which is shared by subcomponents unless they create and set their own.
1434      * @see Component#getInputContext
1435      * @since 1.2
1436      */
getInputContext()1437     public InputContext getInputContext() {
1438         synchronized (inputContextLock) {
1439             if (inputContext == null) {
1440                 inputContext = InputContext.getInstance();
1441             }
1442         }
1443         return inputContext;
1444     }
1445 
1446     /**
1447      * Set the cursor image to a specified cursor.
1448      * <p>
1449      * The method may have no visual effect if the Java platform
1450      * implementation and/or the native system do not support
1451      * changing the mouse cursor shape.
1452      * @param     cursor One of the constants defined
1453      *            by the {@code Cursor} class. If this parameter is null
1454      *            then the cursor for this window will be set to the type
1455      *            Cursor.DEFAULT_CURSOR.
1456      * @see       Component#getCursor
1457      * @see       Cursor
1458      * @since     1.1
1459      */
setCursor(Cursor cursor)1460     public void setCursor(Cursor cursor) {
1461         if (cursor == null) {
1462             cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
1463         }
1464         super.setCursor(cursor);
1465     }
1466 
1467     /**
1468      * Returns the owner of this window.
1469      *
1470      * @return the owner of this window
1471      * @since 1.2
1472      */
getOwner()1473     public Window getOwner() {
1474         return getOwner_NoClientCode();
1475     }
getOwner_NoClientCode()1476     final Window getOwner_NoClientCode() {
1477         return (Window)parent;
1478     }
1479 
1480     /**
1481      * Return an array containing all the windows this
1482      * window currently owns.
1483      *
1484      * @return the array of all the owned windows
1485      * @since 1.2
1486      */
getOwnedWindows()1487     public Window[] getOwnedWindows() {
1488         return getOwnedWindows_NoClientCode();
1489     }
getOwnedWindows_NoClientCode()1490     final Window[] getOwnedWindows_NoClientCode() {
1491         Window[] realCopy;
1492 
1493         synchronized(ownedWindowList) {
1494             // Recall that ownedWindowList is actually a Vector of
1495             // WeakReferences and calling get() on one of these references
1496             // may return null. Make two arrays-- one the size of the
1497             // Vector (fullCopy with size fullSize), and one the size of
1498             // all non-null get()s (realCopy with size realSize).
1499             int fullSize = ownedWindowList.size();
1500             int realSize = 0;
1501             Window[] fullCopy = new Window[fullSize];
1502 
1503             for (int i = 0; i < fullSize; i++) {
1504                 fullCopy[realSize] = ownedWindowList.elementAt(i).get();
1505 
1506                 if (fullCopy[realSize] != null) {
1507                     realSize++;
1508                 }
1509             }
1510 
1511             if (fullSize != realSize) {
1512                 realCopy = Arrays.copyOf(fullCopy, realSize);
1513             } else {
1514                 realCopy = fullCopy;
1515             }
1516         }
1517 
1518         return realCopy;
1519     }
1520 
isModalBlocked()1521     boolean isModalBlocked() {
1522         return modalBlocker != null;
1523     }
1524 
setModalBlocked(Dialog blocker, boolean blocked, boolean peerCall)1525     void setModalBlocked(Dialog blocker, boolean blocked, boolean peerCall) {
1526         this.modalBlocker = blocked ? blocker : null;
1527         if (peerCall) {
1528             WindowPeer peer = (WindowPeer)this.peer;
1529             if (peer != null) {
1530                 peer.setModalBlocked(blocker, blocked);
1531             }
1532         }
1533     }
1534 
getModalBlocker()1535     Dialog getModalBlocker() {
1536         return modalBlocker;
1537     }
1538 
1539     /*
1540      * Returns a list of all displayable Windows, i. e. all the
1541      * Windows which peer is not null.
1542      *
1543      * @see #addNotify
1544      * @see #removeNotify
1545      */
getAllWindows()1546     static IdentityArrayList<Window> getAllWindows() {
1547         synchronized (allWindows) {
1548             IdentityArrayList<Window> v = new IdentityArrayList<Window>();
1549             v.addAll(allWindows);
1550             return v;
1551         }
1552     }
1553 
getAllUnblockedWindows()1554     static IdentityArrayList<Window> getAllUnblockedWindows() {
1555         synchronized (allWindows) {
1556             IdentityArrayList<Window> unblocked = new IdentityArrayList<Window>();
1557             for (int i = 0; i < allWindows.size(); i++) {
1558                 Window w = allWindows.get(i);
1559                 if (!w.isModalBlocked()) {
1560                     unblocked.add(w);
1561                 }
1562             }
1563             return unblocked;
1564         }
1565     }
1566 
getWindows(AppContext appContext)1567     private static Window[] getWindows(AppContext appContext) {
1568         synchronized (Window.class) {
1569             Window[] realCopy;
1570             @SuppressWarnings("unchecked")
1571             Vector<WeakReference<Window>> windowList =
1572                 (Vector<WeakReference<Window>>)appContext.get(Window.class);
1573             if (windowList != null) {
1574                 int fullSize = windowList.size();
1575                 int realSize = 0;
1576                 Window[] fullCopy = new Window[fullSize];
1577                 for (int i = 0; i < fullSize; i++) {
1578                     Window w = windowList.get(i).get();
1579                     if (w != null) {
1580                         fullCopy[realSize++] = w;
1581                     }
1582                 }
1583                 if (fullSize != realSize) {
1584                     realCopy = Arrays.copyOf(fullCopy, realSize);
1585                 } else {
1586                     realCopy = fullCopy;
1587                 }
1588             } else {
1589                 realCopy = new Window[0];
1590             }
1591             return realCopy;
1592         }
1593     }
1594 
1595     /**
1596      * Returns an array of all {@code Window}s, both owned and ownerless,
1597      * created by this application.
1598      * If called from an applet, the array includes only the {@code Window}s
1599      * accessible by that applet.
1600      * <p>
1601      * <b>Warning:</b> this method may return system created windows, such
1602      * as a print dialog. Applications should not assume the existence of
1603      * these dialogs, nor should an application assume anything about these
1604      * dialogs such as component positions, {@code LayoutManager}s
1605      * or serialization.
1606      *
1607      * @return the array of all the {@code Window}s created by the application
1608      * @see Frame#getFrames
1609      * @see Window#getOwnerlessWindows
1610      *
1611      * @since 1.6
1612      */
getWindows()1613     public static Window[] getWindows() {
1614         return getWindows(AppContext.getAppContext());
1615     }
1616 
1617     /**
1618      * Returns an array of all {@code Window}s created by this application
1619      * that have no owner. They include {@code Frame}s and ownerless
1620      * {@code Dialog}s and {@code Window}s.
1621      * If called from an applet, the array includes only the {@code Window}s
1622      * accessible by that applet.
1623      * <p>
1624      * <b>Warning:</b> this method may return system created windows, such
1625      * as a print dialog. Applications should not assume the existence of
1626      * these dialogs, nor should an application assume anything about these
1627      * dialogs such as component positions, {@code LayoutManager}s
1628      * or serialization.
1629      *
1630      * @return the array of all the ownerless {@code Window}s
1631      *         created by this application
1632      * @see Frame#getFrames
1633      * @see Window#getWindows()
1634      *
1635      * @since 1.6
1636      */
getOwnerlessWindows()1637     public static Window[] getOwnerlessWindows() {
1638         Window[] allWindows = Window.getWindows();
1639 
1640         int ownerlessCount = 0;
1641         for (Window w : allWindows) {
1642             if (w.getOwner() == null) {
1643                 ownerlessCount++;
1644             }
1645         }
1646 
1647         Window[] ownerless = new Window[ownerlessCount];
1648         int c = 0;
1649         for (Window w : allWindows) {
1650             if (w.getOwner() == null) {
1651                 ownerless[c++] = w;
1652             }
1653         }
1654 
1655         return ownerless;
1656     }
1657 
getDocumentRoot()1658     Window getDocumentRoot() {
1659         synchronized (getTreeLock()) {
1660             Window w = this;
1661             while (w.getOwner() != null) {
1662                 w = w.getOwner();
1663             }
1664             return w;
1665         }
1666     }
1667 
1668     /**
1669      * Specifies the modal exclusion type for this window. If a window is modal
1670      * excluded, it is not blocked by some modal dialogs. See {@link
1671      * java.awt.Dialog.ModalExclusionType Dialog.ModalExclusionType} for
1672      * possible modal exclusion types.
1673      * <p>
1674      * If the given type is not supported, {@code NO_EXCLUDE} is used.
1675      * <p>
1676      * Note: changing the modal exclusion type for a visible window may have no
1677      * effect until it is hidden and then shown again.
1678      *
1679      * @param exclusionType the modal exclusion type for this window; a {@code null}
1680      *     value is equivalent to {@link Dialog.ModalExclusionType#NO_EXCLUDE
1681      *     NO_EXCLUDE}
1682      * @throws SecurityException if the calling thread does not have permission
1683      *     to set the modal exclusion property to the window with the given
1684      *     {@code exclusionType}
1685      * @see java.awt.Dialog.ModalExclusionType
1686      * @see java.awt.Window#getModalExclusionType
1687      * @see java.awt.Toolkit#isModalExclusionTypeSupported
1688      *
1689      * @since 1.6
1690      */
setModalExclusionType(Dialog.ModalExclusionType exclusionType)1691     public void setModalExclusionType(Dialog.ModalExclusionType exclusionType) {
1692         if (exclusionType == null) {
1693             exclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
1694         }
1695         if (!Toolkit.getDefaultToolkit().isModalExclusionTypeSupported(exclusionType)) {
1696             exclusionType = Dialog.ModalExclusionType.NO_EXCLUDE;
1697         }
1698         if (modalExclusionType == exclusionType) {
1699             return;
1700         }
1701         if (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE) {
1702             SecurityManager sm = System.getSecurityManager();
1703             if (sm != null) {
1704                 sm.checkPermission(AWTPermissions.TOOLKIT_MODALITY_PERMISSION);
1705             }
1706         }
1707         modalExclusionType = exclusionType;
1708 
1709         // if we want on-fly changes, we need to uncomment the lines below
1710         //   and override the method in Dialog to use modalShow() instead
1711         //   of updateChildrenBlocking()
1712  /*
1713         if (isModalBlocked()) {
1714             modalBlocker.unblockWindow(this);
1715         }
1716         Dialog.checkShouldBeBlocked(this);
1717         updateChildrenBlocking();
1718  */
1719     }
1720 
1721     /**
1722      * Returns the modal exclusion type of this window.
1723      *
1724      * @return the modal exclusion type of this window
1725      *
1726      * @see java.awt.Dialog.ModalExclusionType
1727      * @see java.awt.Window#setModalExclusionType
1728      *
1729      * @since 1.6
1730      */
getModalExclusionType()1731     public Dialog.ModalExclusionType getModalExclusionType() {
1732         return modalExclusionType;
1733     }
1734 
isModalExcluded(Dialog.ModalExclusionType exclusionType)1735     boolean isModalExcluded(Dialog.ModalExclusionType exclusionType) {
1736         if ((modalExclusionType != null) &&
1737             modalExclusionType.compareTo(exclusionType) >= 0)
1738         {
1739             return true;
1740         }
1741         Window owner = getOwner_NoClientCode();
1742         return (owner != null) && owner.isModalExcluded(exclusionType);
1743     }
1744 
updateChildrenBlocking()1745     void updateChildrenBlocking() {
1746         Vector<Window> childHierarchy = new Vector<Window>();
1747         Window[] ownedWindows = getOwnedWindows();
1748         for (int i = 0; i < ownedWindows.length; i++) {
1749             childHierarchy.add(ownedWindows[i]);
1750         }
1751         int k = 0;
1752         while (k < childHierarchy.size()) {
1753             Window w = childHierarchy.get(k);
1754             if (w.isVisible()) {
1755                 if (w.isModalBlocked()) {
1756                     Dialog blocker = w.getModalBlocker();
1757                     blocker.unblockWindow(w);
1758                 }
1759                 Dialog.checkShouldBeBlocked(w);
1760                 Window[] wOwned = w.getOwnedWindows();
1761                 for (int j = 0; j < wOwned.length; j++) {
1762                     childHierarchy.add(wOwned[j]);
1763                 }
1764             }
1765             k++;
1766         }
1767     }
1768 
1769     /**
1770      * Adds the specified window listener to receive window events from
1771      * this window.
1772      * If l is null, no exception is thrown and no action is performed.
1773      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1774      * >AWT Threading Issues</a> for details on AWT's threading model.
1775      *
1776      * @param   l the window listener
1777      * @see #removeWindowListener
1778      * @see #getWindowListeners
1779      */
addWindowListener(WindowListener l)1780     public synchronized void addWindowListener(WindowListener l) {
1781         if (l == null) {
1782             return;
1783         }
1784         newEventsOnly = true;
1785         windowListener = AWTEventMulticaster.add(windowListener, l);
1786     }
1787 
1788     /**
1789      * Adds the specified window state listener to receive window
1790      * events from this window.  If {@code l} is {@code null},
1791      * no exception is thrown and no action is performed.
1792      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1793      * >AWT Threading Issues</a> for details on AWT's threading model.
1794      *
1795      * @param   l the window state listener
1796      * @see #removeWindowStateListener
1797      * @see #getWindowStateListeners
1798      * @since 1.4
1799      */
addWindowStateListener(WindowStateListener l)1800     public synchronized void addWindowStateListener(WindowStateListener l) {
1801         if (l == null) {
1802             return;
1803         }
1804         windowStateListener = AWTEventMulticaster.add(windowStateListener, l);
1805         newEventsOnly = true;
1806     }
1807 
1808     /**
1809      * Adds the specified window focus listener to receive window events
1810      * from this window.
1811      * If l is null, no exception is thrown and no action is performed.
1812      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1813      * >AWT Threading Issues</a> for details on AWT's threading model.
1814      *
1815      * @param   l the window focus listener
1816      * @see #removeWindowFocusListener
1817      * @see #getWindowFocusListeners
1818      * @since 1.4
1819      */
addWindowFocusListener(WindowFocusListener l)1820     public synchronized void addWindowFocusListener(WindowFocusListener l) {
1821         if (l == null) {
1822             return;
1823         }
1824         windowFocusListener = AWTEventMulticaster.add(windowFocusListener, l);
1825         newEventsOnly = true;
1826     }
1827 
1828     /**
1829      * Removes the specified window listener so that it no longer
1830      * receives window events from this window.
1831      * If l is null, no exception is thrown and no action is performed.
1832      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1833      * >AWT Threading Issues</a> for details on AWT's threading model.
1834      *
1835      * @param   l the window listener
1836      * @see #addWindowListener
1837      * @see #getWindowListeners
1838      */
removeWindowListener(WindowListener l)1839     public synchronized void removeWindowListener(WindowListener l) {
1840         if (l == null) {
1841             return;
1842         }
1843         windowListener = AWTEventMulticaster.remove(windowListener, l);
1844     }
1845 
1846     /**
1847      * Removes the specified window state listener so that it no
1848      * longer receives window events from this window.  If
1849      * {@code l} is {@code null}, no exception is thrown and
1850      * no action is performed.
1851      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1852      * >AWT Threading Issues</a> for details on AWT's threading model.
1853      *
1854      * @param   l the window state listener
1855      * @see #addWindowStateListener
1856      * @see #getWindowStateListeners
1857      * @since 1.4
1858      */
removeWindowStateListener(WindowStateListener l)1859     public synchronized void removeWindowStateListener(WindowStateListener l) {
1860         if (l == null) {
1861             return;
1862         }
1863         windowStateListener = AWTEventMulticaster.remove(windowStateListener, l);
1864     }
1865 
1866     /**
1867      * Removes the specified window focus listener so that it no longer
1868      * receives window events from this window.
1869      * If l is null, no exception is thrown and no action is performed.
1870      * <p>Refer to <a href="doc-files/AWTThreadIssues.html#ListenersThreads"
1871      * >AWT Threading Issues</a> for details on AWT's threading model.
1872      *
1873      * @param   l the window focus listener
1874      * @see #addWindowFocusListener
1875      * @see #getWindowFocusListeners
1876      * @since 1.4
1877      */
removeWindowFocusListener(WindowFocusListener l)1878     public synchronized void removeWindowFocusListener(WindowFocusListener l) {
1879         if (l == null) {
1880             return;
1881         }
1882         windowFocusListener = AWTEventMulticaster.remove(windowFocusListener, l);
1883     }
1884 
1885     /**
1886      * Returns an array of all the window listeners
1887      * registered on this window.
1888      *
1889      * @return all of this window's {@code WindowListener}s
1890      *         or an empty array if no window
1891      *         listeners are currently registered
1892      *
1893      * @see #addWindowListener
1894      * @see #removeWindowListener
1895      * @since 1.4
1896      */
getWindowListeners()1897     public synchronized WindowListener[] getWindowListeners() {
1898         return getListeners(WindowListener.class);
1899     }
1900 
1901     /**
1902      * Returns an array of all the window focus listeners
1903      * registered on this window.
1904      *
1905      * @return all of this window's {@code WindowFocusListener}s
1906      *         or an empty array if no window focus
1907      *         listeners are currently registered
1908      *
1909      * @see #addWindowFocusListener
1910      * @see #removeWindowFocusListener
1911      * @since 1.4
1912      */
getWindowFocusListeners()1913     public synchronized WindowFocusListener[] getWindowFocusListeners() {
1914         return getListeners(WindowFocusListener.class);
1915     }
1916 
1917     /**
1918      * Returns an array of all the window state listeners
1919      * registered on this window.
1920      *
1921      * @return all of this window's {@code WindowStateListener}s
1922      *         or an empty array if no window state
1923      *         listeners are currently registered
1924      *
1925      * @see #addWindowStateListener
1926      * @see #removeWindowStateListener
1927      * @since 1.4
1928      */
getWindowStateListeners()1929     public synchronized WindowStateListener[] getWindowStateListeners() {
1930         return getListeners(WindowStateListener.class);
1931     }
1932 
1933 
1934     /**
1935      * Returns an array of all the objects currently registered
1936      * as <code><em>Foo</em>Listener</code>s
1937      * upon this {@code Window}.
1938      * <code><em>Foo</em>Listener</code>s are registered using the
1939      * <code>add<em>Foo</em>Listener</code> method.
1940      *
1941      * <p>
1942      *
1943      * You can specify the {@code listenerType} argument
1944      * with a class literal, such as
1945      * <code><em>Foo</em>Listener.class</code>.
1946      * For example, you can query a
1947      * {@code Window w}
1948      * for its window listeners with the following code:
1949      *
1950      * <pre>WindowListener[] wls = (WindowListener[])(w.getListeners(WindowListener.class));</pre>
1951      *
1952      * If no such listeners exist, this method returns an empty array.
1953      *
1954      * @param listenerType the type of listeners requested; this parameter
1955      *          should specify an interface that descends from
1956      *          {@code java.util.EventListener}
1957      * @return an array of all objects registered as
1958      *          <code><em>Foo</em>Listener</code>s on this window,
1959      *          or an empty array if no such
1960      *          listeners have been added
1961      * @exception ClassCastException if {@code listenerType}
1962      *          doesn't specify a class or interface that implements
1963      *          {@code java.util.EventListener}
1964      * @exception NullPointerException if {@code listenerType} is {@code null}
1965      *
1966      * @see #getWindowListeners
1967      * @since 1.3
1968      */
getListeners(Class<T> listenerType)1969     public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
1970         EventListener l = null;
1971         if (listenerType == WindowFocusListener.class) {
1972             l = windowFocusListener;
1973         } else if (listenerType == WindowStateListener.class) {
1974             l = windowStateListener;
1975         } else if (listenerType == WindowListener.class) {
1976             l = windowListener;
1977         } else {
1978             return super.getListeners(listenerType);
1979         }
1980         return AWTEventMulticaster.getListeners(l, listenerType);
1981     }
1982 
1983     // REMIND: remove when filtering is handled at lower level
eventEnabled(AWTEvent e)1984     boolean eventEnabled(AWTEvent e) {
1985         switch(e.id) {
1986           case WindowEvent.WINDOW_OPENED:
1987           case WindowEvent.WINDOW_CLOSING:
1988           case WindowEvent.WINDOW_CLOSED:
1989           case WindowEvent.WINDOW_ICONIFIED:
1990           case WindowEvent.WINDOW_DEICONIFIED:
1991           case WindowEvent.WINDOW_ACTIVATED:
1992           case WindowEvent.WINDOW_DEACTIVATED:
1993             if ((eventMask & AWTEvent.WINDOW_EVENT_MASK) != 0 ||
1994                 windowListener != null) {
1995                 return true;
1996             }
1997             return false;
1998           case WindowEvent.WINDOW_GAINED_FOCUS:
1999           case WindowEvent.WINDOW_LOST_FOCUS:
2000             if ((eventMask & AWTEvent.WINDOW_FOCUS_EVENT_MASK) != 0 ||
2001                 windowFocusListener != null) {
2002                 return true;
2003             }
2004             return false;
2005           case WindowEvent.WINDOW_STATE_CHANGED:
2006             if ((eventMask & AWTEvent.WINDOW_STATE_EVENT_MASK) != 0 ||
2007                 windowStateListener != null) {
2008                 return true;
2009             }
2010             return false;
2011           default:
2012             break;
2013         }
2014         return super.eventEnabled(e);
2015     }
2016 
2017     /**
2018      * Processes events on this window. If the event is an
2019      * {@code WindowEvent}, it invokes the
2020      * {@code processWindowEvent} method, else it invokes its
2021      * superclass's {@code processEvent}.
2022      * <p>Note that if the event parameter is {@code null}
2023      * the behavior is unspecified and may result in an
2024      * exception.
2025      *
2026      * @param e the event
2027      */
processEvent(AWTEvent e)2028     protected void processEvent(AWTEvent e) {
2029         if (e instanceof WindowEvent) {
2030             switch (e.getID()) {
2031                 case WindowEvent.WINDOW_OPENED:
2032                 case WindowEvent.WINDOW_CLOSING:
2033                 case WindowEvent.WINDOW_CLOSED:
2034                 case WindowEvent.WINDOW_ICONIFIED:
2035                 case WindowEvent.WINDOW_DEICONIFIED:
2036                 case WindowEvent.WINDOW_ACTIVATED:
2037                 case WindowEvent.WINDOW_DEACTIVATED:
2038                     processWindowEvent((WindowEvent)e);
2039                     break;
2040                 case WindowEvent.WINDOW_GAINED_FOCUS:
2041                 case WindowEvent.WINDOW_LOST_FOCUS:
2042                     processWindowFocusEvent((WindowEvent)e);
2043                     break;
2044                 case WindowEvent.WINDOW_STATE_CHANGED:
2045                     processWindowStateEvent((WindowEvent)e);
2046                     break;
2047             }
2048             return;
2049         }
2050         super.processEvent(e);
2051     }
2052 
2053     /**
2054      * Processes window events occurring on this window by
2055      * dispatching them to any registered WindowListener objects.
2056      * NOTE: This method will not be called unless window events
2057      * are enabled for this component; this happens when one of the
2058      * following occurs:
2059      * <ul>
2060      * <li>A WindowListener object is registered via
2061      *     {@code addWindowListener}
2062      * <li>Window events are enabled via {@code enableEvents}
2063      * </ul>
2064      * <p>Note that if the event parameter is {@code null}
2065      * the behavior is unspecified and may result in an
2066      * exception.
2067      *
2068      * @param e the window event
2069      * @see Component#enableEvents
2070      */
processWindowEvent(WindowEvent e)2071     protected void processWindowEvent(WindowEvent e) {
2072         WindowListener listener = windowListener;
2073         if (listener != null) {
2074             switch(e.getID()) {
2075                 case WindowEvent.WINDOW_OPENED:
2076                     listener.windowOpened(e);
2077                     break;
2078                 case WindowEvent.WINDOW_CLOSING:
2079                     listener.windowClosing(e);
2080                     break;
2081                 case WindowEvent.WINDOW_CLOSED:
2082                     listener.windowClosed(e);
2083                     break;
2084                 case WindowEvent.WINDOW_ICONIFIED:
2085                     listener.windowIconified(e);
2086                     break;
2087                 case WindowEvent.WINDOW_DEICONIFIED:
2088                     listener.windowDeiconified(e);
2089                     break;
2090                 case WindowEvent.WINDOW_ACTIVATED:
2091                     listener.windowActivated(e);
2092                     break;
2093                 case WindowEvent.WINDOW_DEACTIVATED:
2094                     listener.windowDeactivated(e);
2095                     break;
2096                 default:
2097                     break;
2098             }
2099         }
2100     }
2101 
2102     /**
2103      * Processes window focus event occurring on this window by
2104      * dispatching them to any registered WindowFocusListener objects.
2105      * NOTE: this method will not be called unless window focus events
2106      * are enabled for this window. This happens when one of the
2107      * following occurs:
2108      * <ul>
2109      * <li>a WindowFocusListener is registered via
2110      *     {@code addWindowFocusListener}
2111      * <li>Window focus events are enabled via {@code enableEvents}
2112      * </ul>
2113      * <p>Note that if the event parameter is {@code null}
2114      * the behavior is unspecified and may result in an
2115      * exception.
2116      *
2117      * @param e the window focus event
2118      * @see Component#enableEvents
2119      * @since 1.4
2120      */
processWindowFocusEvent(WindowEvent e)2121     protected void processWindowFocusEvent(WindowEvent e) {
2122         WindowFocusListener listener = windowFocusListener;
2123         if (listener != null) {
2124             switch (e.getID()) {
2125                 case WindowEvent.WINDOW_GAINED_FOCUS:
2126                     listener.windowGainedFocus(e);
2127                     break;
2128                 case WindowEvent.WINDOW_LOST_FOCUS:
2129                     listener.windowLostFocus(e);
2130                     break;
2131                 default:
2132                     break;
2133             }
2134         }
2135     }
2136 
2137     /**
2138      * Processes window state event occurring on this window by
2139      * dispatching them to any registered {@code WindowStateListener}
2140      * objects.
2141      * NOTE: this method will not be called unless window state events
2142      * are enabled for this window.  This happens when one of the
2143      * following occurs:
2144      * <ul>
2145      * <li>a {@code WindowStateListener} is registered via
2146      *    {@code addWindowStateListener}
2147      * <li>window state events are enabled via {@code enableEvents}
2148      * </ul>
2149      * <p>Note that if the event parameter is {@code null}
2150      * the behavior is unspecified and may result in an
2151      * exception.
2152      *
2153      * @param e the window state event
2154      * @see java.awt.Component#enableEvents
2155      * @since 1.4
2156      */
processWindowStateEvent(WindowEvent e)2157     protected void processWindowStateEvent(WindowEvent e) {
2158         WindowStateListener listener = windowStateListener;
2159         if (listener != null) {
2160             switch (e.getID()) {
2161                 case WindowEvent.WINDOW_STATE_CHANGED:
2162                     listener.windowStateChanged(e);
2163                     break;
2164                 default:
2165                     break;
2166             }
2167         }
2168     }
2169 
2170     /**
2171      * Implements a debugging hook -- checks to see if
2172      * the user has typed <i>control-shift-F1</i>.  If so,
2173      * the list of child windows is dumped to {@code System.out}.
2174      * @param e  the keyboard event
2175      */
preProcessKeyEvent(KeyEvent e)2176     void preProcessKeyEvent(KeyEvent e) {
2177         // Dump the list of child windows to System.out if debug is enabled.
2178         if (DebugSettings.getInstance().getBoolean("on", false)) {
2179             if (e.isActionKey() && e.getKeyCode() == KeyEvent.VK_F1 &&
2180                     e.isControlDown() && e.isShiftDown() &&
2181                     e.getID() == KeyEvent.KEY_PRESSED) {
2182                 list(System.out, 0);
2183             }
2184         }
2185     }
2186 
postProcessKeyEvent(KeyEvent e)2187     void postProcessKeyEvent(KeyEvent e) {
2188         // Do nothing
2189     }
2190 
2191 
2192     /**
2193      * Sets whether this window should always be above other windows.  If
2194      * there are multiple always-on-top windows, their relative order is
2195      * unspecified and platform dependent.
2196      * <p>
2197      * If some other window is already always-on-top then the
2198      * relative order between these windows is unspecified (depends on
2199      * platform).  No window can be brought to be over the always-on-top
2200      * window except maybe another always-on-top window.
2201      * <p>
2202      * All windows owned by an always-on-top window inherit this state and
2203      * automatically become always-on-top.  If a window ceases to be
2204      * always-on-top, the windows that it owns will no longer be
2205      * always-on-top.  When an always-on-top window is sent {@link #toBack
2206      * toBack}, its always-on-top state is set to {@code false}.
2207      *
2208      * <p> When this method is called on a window with a value of
2209      * {@code true}, and the window is visible and the platform
2210      * supports always-on-top for this window, the window is immediately
2211      * brought forward, "sticking" it in the top-most position. If the
2212      * window isn`t currently visible, this method sets the always-on-top
2213      * state to {@code true} but does not bring the window forward.
2214      * When the window is later shown, it will be always-on-top.
2215      *
2216      * <p> When this method is called on a window with a value of
2217      * {@code false} the always-on-top state is set to normal. It may also
2218      * cause an unspecified, platform-dependent change in the z-order of
2219      * top-level windows, but other always-on-top windows will remain in
2220      * top-most position. Calling this method with a value of {@code false}
2221      * on a window that has a normal state has no effect.
2222      *
2223      * <p><b>Note</b>: some platforms might not support always-on-top
2224      * windows.  To detect if always-on-top windows are supported by the
2225      * current platform, use {@link Toolkit#isAlwaysOnTopSupported()} and
2226      * {@link Window#isAlwaysOnTopSupported()}.  If always-on-top mode
2227      * isn't supported for this window or this window's toolkit does not
2228      * support always-on-top windows, calling this method has no effect.
2229      * <p>
2230      * If a SecurityManager is installed, the calling thread must be
2231      * granted the AWTPermission "setWindowAlwaysOnTop" in
2232      * order to set the value of this property. If this
2233      * permission is not granted, this method will throw a
2234      * SecurityException, and the current value of the property will
2235      * be left unchanged.
2236      *
2237      * @param alwaysOnTop true if the window should always be above other
2238      *        windows
2239      * @throws SecurityException if the calling thread does not have
2240      *         permission to set the value of always-on-top property
2241      *
2242      * @see #isAlwaysOnTop
2243      * @see #toFront
2244      * @see #toBack
2245      * @see AWTPermission
2246      * @see #isAlwaysOnTopSupported
2247      * @see #getToolkit
2248      * @see Toolkit#isAlwaysOnTopSupported
2249      * @since 1.5
2250      */
setAlwaysOnTop(boolean alwaysOnTop)2251     public final void setAlwaysOnTop(boolean alwaysOnTop) throws SecurityException {
2252         SecurityManager security = System.getSecurityManager();
2253         if (security != null) {
2254             security.checkPermission(AWTPermissions.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION);
2255         }
2256 
2257         boolean oldAlwaysOnTop;
2258         synchronized(this) {
2259             oldAlwaysOnTop = this.alwaysOnTop;
2260             this.alwaysOnTop = alwaysOnTop;
2261         }
2262         if (oldAlwaysOnTop != alwaysOnTop ) {
2263             if (isAlwaysOnTopSupported()) {
2264                 WindowPeer peer = (WindowPeer)this.peer;
2265                 synchronized(getTreeLock()) {
2266                     if (peer != null) {
2267                         peer.updateAlwaysOnTopState();
2268                     }
2269                 }
2270             }
2271             firePropertyChange("alwaysOnTop", oldAlwaysOnTop, alwaysOnTop);
2272         }
2273         setOwnedWindowsAlwaysOnTop(alwaysOnTop);
2274     }
2275 
2276     @SuppressWarnings({"rawtypes", "unchecked"})
setOwnedWindowsAlwaysOnTop(boolean alwaysOnTop)2277     private void setOwnedWindowsAlwaysOnTop(boolean alwaysOnTop) {
2278         WeakReference<Window>[] ownedWindowArray;
2279         synchronized (ownedWindowList) {
2280             ownedWindowArray = new WeakReference[ownedWindowList.size()];
2281             ownedWindowList.copyInto(ownedWindowArray);
2282         }
2283 
2284         for (WeakReference<Window> ref : ownedWindowArray) {
2285             Window window = ref.get();
2286             if (window != null) {
2287                 try {
2288                     window.setAlwaysOnTop(alwaysOnTop);
2289                 } catch (SecurityException ignore) {
2290                 }
2291             }
2292         }
2293     }
2294 
2295     /**
2296      * Returns whether the always-on-top mode is supported for this
2297      * window. Some platforms may not support always-on-top windows, some
2298      * may support only some kinds of top-level windows; for example,
2299      * a platform may not support always-on-top modal dialogs.
2300      *
2301      * @return {@code true}, if the always-on-top mode is supported for
2302      *         this window and this window's toolkit supports always-on-top windows,
2303      *         {@code false} otherwise
2304      *
2305      * @see #setAlwaysOnTop(boolean)
2306      * @see #getToolkit
2307      * @see Toolkit#isAlwaysOnTopSupported
2308      * @since 1.6
2309      */
isAlwaysOnTopSupported()2310     public boolean isAlwaysOnTopSupported() {
2311         return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
2312     }
2313 
2314 
2315     /**
2316      * Returns whether this window is an always-on-top window.
2317      * @return {@code true}, if the window is in always-on-top state,
2318      *         {@code false} otherwise
2319      * @see #setAlwaysOnTop
2320      * @since 1.5
2321      */
isAlwaysOnTop()2322     public final boolean isAlwaysOnTop() {
2323         return alwaysOnTop;
2324     }
2325 
2326 
2327     /**
2328      * Returns the child Component of this Window that has focus if this Window
2329      * is focused; returns null otherwise.
2330      *
2331      * @return the child Component with focus, or null if this Window is not
2332      *         focused
2333      * @see #getMostRecentFocusOwner
2334      * @see #isFocused
2335      */
getFocusOwner()2336     public Component getFocusOwner() {
2337         return (isFocused())
2338             ? KeyboardFocusManager.getCurrentKeyboardFocusManager().
2339                   getFocusOwner()
2340             : null;
2341     }
2342 
2343     /**
2344      * Returns the child Component of this Window that will receive the focus
2345      * when this Window is focused. If this Window is currently focused, this
2346      * method returns the same Component as {@code getFocusOwner()}. If
2347      * this Window is not focused, then the child Component that most recently
2348      * requested focus will be returned. If no child Component has ever
2349      * requested focus, and this is a focusable Window, then this Window's
2350      * initial focusable Component is returned. If no child Component has ever
2351      * requested focus, and this is a non-focusable Window, null is returned.
2352      *
2353      * @return the child Component that will receive focus when this Window is
2354      *         focused
2355      * @see #getFocusOwner
2356      * @see #isFocused
2357      * @see #isFocusableWindow
2358      * @since 1.4
2359      */
getMostRecentFocusOwner()2360     public Component getMostRecentFocusOwner() {
2361         if (isFocused()) {
2362             return getFocusOwner();
2363         } else {
2364             Component mostRecent =
2365                 KeyboardFocusManager.getMostRecentFocusOwner(this);
2366             if (mostRecent != null) {
2367                 return mostRecent;
2368             } else {
2369                 return (isFocusableWindow())
2370                     ? getFocusTraversalPolicy().getInitialComponent(this)
2371                     : null;
2372             }
2373         }
2374     }
2375 
2376     /**
2377      * Returns whether this Window is active. Only a Frame or a Dialog may be
2378      * active. The native windowing system may denote the active Window or its
2379      * children with special decorations, such as a highlighted title bar. The
2380      * active Window is always either the focused Window, or the first Frame or
2381      * Dialog that is an owner of the focused Window.
2382      *
2383      * @return whether this is the active Window.
2384      * @see #isFocused
2385      * @since 1.4
2386      */
isActive()2387     public boolean isActive() {
2388         return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
2389                 getActiveWindow() == this);
2390     }
2391 
2392     /**
2393      * Returns whether this Window is focused. If there exists a focus owner,
2394      * the focused Window is the Window that is, or contains, that focus owner.
2395      * If there is no focus owner, then no Window is focused.
2396      * <p>
2397      * If the focused Window is a Frame or a Dialog it is also the active
2398      * Window. Otherwise, the active Window is the first Frame or Dialog that
2399      * is an owner of the focused Window.
2400      *
2401      * @return whether this is the focused Window.
2402      * @see #isActive
2403      * @since 1.4
2404      */
isFocused()2405     public boolean isFocused() {
2406         return (KeyboardFocusManager.getCurrentKeyboardFocusManager().
2407                 getGlobalFocusedWindow() == this);
2408     }
2409 
2410     /**
2411      * Gets a focus traversal key for this Window. (See {@code
2412      * setFocusTraversalKeys} for a full description of each key.)
2413      * <p>
2414      * If the traversal key has not been explicitly set for this Window,
2415      * then this Window's parent's traversal key is returned. If the
2416      * traversal key has not been explicitly set for any of this Window's
2417      * ancestors, then the current KeyboardFocusManager's default traversal key
2418      * is returned.
2419      *
2420      * @param id one of KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2421      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2422      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2423      *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2424      * @return the AWTKeyStroke for the specified key
2425      * @see Container#setFocusTraversalKeys
2426      * @see KeyboardFocusManager#FORWARD_TRAVERSAL_KEYS
2427      * @see KeyboardFocusManager#BACKWARD_TRAVERSAL_KEYS
2428      * @see KeyboardFocusManager#UP_CYCLE_TRAVERSAL_KEYS
2429      * @see KeyboardFocusManager#DOWN_CYCLE_TRAVERSAL_KEYS
2430      * @throws IllegalArgumentException if id is not one of
2431      *         KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS,
2432      *         KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS,
2433      *         KeyboardFocusManager.UP_CYCLE_TRAVERSAL_KEYS, or
2434      *         KeyboardFocusManager.DOWN_CYCLE_TRAVERSAL_KEYS
2435      * @since 1.4
2436      */
2437     @SuppressWarnings("unchecked")
getFocusTraversalKeys(int id)2438     public Set<AWTKeyStroke> getFocusTraversalKeys(int id) {
2439         if (id < 0 || id >= KeyboardFocusManager.TRAVERSAL_KEY_LENGTH) {
2440             throw new IllegalArgumentException("invalid focus traversal key identifier");
2441         }
2442 
2443         // Okay to return Set directly because it is an unmodifiable view
2444         @SuppressWarnings("rawtypes")
2445         Set keystrokes = (focusTraversalKeys != null)
2446             ? focusTraversalKeys[id]
2447             : null;
2448 
2449         if (keystrokes != null) {
2450             return keystrokes;
2451         } else {
2452             return KeyboardFocusManager.getCurrentKeyboardFocusManager().
2453                 getDefaultFocusTraversalKeys(id);
2454         }
2455     }
2456 
2457     /**
2458      * Does nothing because Windows must always be roots of a focus traversal
2459      * cycle. The passed-in value is ignored.
2460      *
2461      * @param focusCycleRoot this value is ignored
2462      * @see #isFocusCycleRoot
2463      * @see Container#setFocusTraversalPolicy
2464      * @see Container#getFocusTraversalPolicy
2465      * @since 1.4
2466      */
setFocusCycleRoot(boolean focusCycleRoot)2467     public final void setFocusCycleRoot(boolean focusCycleRoot) {
2468     }
2469 
2470     /**
2471      * Always returns {@code true} because all Windows must be roots of a
2472      * focus traversal cycle.
2473      *
2474      * @return {@code true}
2475      * @see #setFocusCycleRoot
2476      * @see Container#setFocusTraversalPolicy
2477      * @see Container#getFocusTraversalPolicy
2478      * @since 1.4
2479      */
isFocusCycleRoot()2480     public final boolean isFocusCycleRoot() {
2481         return true;
2482     }
2483 
2484     /**
2485      * Always returns {@code null} because Windows have no ancestors; they
2486      * represent the top of the Component hierarchy.
2487      *
2488      * @return {@code null}
2489      * @see Container#isFocusCycleRoot()
2490      * @since 1.4
2491      */
getFocusCycleRootAncestor()2492     public final Container getFocusCycleRootAncestor() {
2493         return null;
2494     }
2495 
2496     /**
2497      * Returns whether this Window can become the focused Window, that is,
2498      * whether this Window or any of its subcomponents can become the focus
2499      * owner. For a Frame or Dialog to be focusable, its focusable Window state
2500      * must be set to {@code true}. For a Window which is not a Frame or
2501      * Dialog to be focusable, its focusable Window state must be set to
2502      * {@code true}, its nearest owning Frame or Dialog must be
2503      * showing on the screen, and it must contain at least one Component in
2504      * its focus traversal cycle. If any of these conditions is not met, then
2505      * neither this Window nor any of its subcomponents can become the focus
2506      * owner.
2507      *
2508      * @return {@code true} if this Window can be the focused Window;
2509      *         {@code false} otherwise
2510      * @see #getFocusableWindowState
2511      * @see #setFocusableWindowState
2512      * @see #isShowing
2513      * @see Component#isFocusable
2514      * @since 1.4
2515      */
isFocusableWindow()2516     public final boolean isFocusableWindow() {
2517         // If a Window/Frame/Dialog was made non-focusable, then it is always
2518         // non-focusable.
2519         if (!getFocusableWindowState()) {
2520             return false;
2521         }
2522 
2523         // All other tests apply only to Windows.
2524         if (this instanceof Frame || this instanceof Dialog) {
2525             return true;
2526         }
2527 
2528         // A Window must have at least one Component in its root focus
2529         // traversal cycle to be focusable.
2530         if (getFocusTraversalPolicy().getDefaultComponent(this) == null) {
2531             return false;
2532         }
2533 
2534         // A Window's nearest owning Frame or Dialog must be showing on the
2535         // screen.
2536         for (Window owner = getOwner(); owner != null;
2537              owner = owner.getOwner())
2538         {
2539             if (owner instanceof Frame || owner instanceof Dialog) {
2540                 return owner.isShowing();
2541             }
2542         }
2543 
2544         return false;
2545     }
2546 
2547     /**
2548      * Returns whether this Window can become the focused Window if it meets
2549      * the other requirements outlined in {@code isFocusableWindow}. If
2550      * this method returns {@code false}, then
2551      * {@code isFocusableWindow} will return {@code false} as well.
2552      * If this method returns {@code true}, then
2553      * {@code isFocusableWindow} may return {@code true} or
2554      * {@code false} depending upon the other requirements which must be
2555      * met in order for a Window to be focusable.
2556      * <p>
2557      * By default, all Windows have a focusable Window state of
2558      * {@code true}.
2559      *
2560      * @return whether this Window can be the focused Window
2561      * @see #isFocusableWindow
2562      * @see #setFocusableWindowState
2563      * @see #isShowing
2564      * @see Component#setFocusable
2565      * @since 1.4
2566      */
getFocusableWindowState()2567     public boolean getFocusableWindowState() {
2568         return focusableWindowState;
2569     }
2570 
2571     /**
2572      * Sets whether this Window can become the focused Window if it meets
2573      * the other requirements outlined in {@code isFocusableWindow}. If
2574      * this Window's focusable Window state is set to {@code false}, then
2575      * {@code isFocusableWindow} will return {@code false}. If this
2576      * Window's focusable Window state is set to {@code true}, then
2577      * {@code isFocusableWindow} may return {@code true} or
2578      * {@code false} depending upon the other requirements which must be
2579      * met in order for a Window to be focusable.
2580      * <p>
2581      * Setting a Window's focusability state to {@code false} is the
2582      * standard mechanism for an application to identify to the AWT a Window
2583      * which will be used as a floating palette or toolbar, and thus should be
2584      * a non-focusable Window.
2585      *
2586      * Setting the focusability state on a visible {@code Window}
2587      * can have a delayed effect on some platforms &#8212; the actual
2588      * change may happen only when the {@code Window} becomes
2589      * hidden and then visible again.  To ensure consistent behavior
2590      * across platforms, set the {@code Window}'s focusable state
2591      * when the {@code Window} is invisible and then show it.
2592      *
2593      * @param focusableWindowState whether this Window can be the focused
2594      *        Window
2595      * @see #isFocusableWindow
2596      * @see #getFocusableWindowState
2597      * @see #isShowing
2598      * @see Component#setFocusable
2599      * @since 1.4
2600      */
setFocusableWindowState(boolean focusableWindowState)2601     public void setFocusableWindowState(boolean focusableWindowState) {
2602         boolean oldFocusableWindowState;
2603         synchronized (this) {
2604             oldFocusableWindowState = this.focusableWindowState;
2605             this.focusableWindowState = focusableWindowState;
2606         }
2607         WindowPeer peer = (WindowPeer)this.peer;
2608         if (peer != null) {
2609             peer.updateFocusableWindowState();
2610         }
2611         firePropertyChange("focusableWindowState", oldFocusableWindowState,
2612                            focusableWindowState);
2613         if (oldFocusableWindowState && !focusableWindowState && isFocused()) {
2614             for (Window owner = getOwner();
2615                  owner != null;
2616                  owner = owner.getOwner())
2617                 {
2618                     Component toFocus =
2619                         KeyboardFocusManager.getMostRecentFocusOwner(owner);
2620                     if (toFocus != null && toFocus.requestFocus(false, FocusEvent.Cause.ACTIVATION)) {
2621                         return;
2622                     }
2623                 }
2624             KeyboardFocusManager.getCurrentKeyboardFocusManager().
2625                 clearGlobalFocusOwnerPriv();
2626         }
2627     }
2628 
2629     /**
2630      * Sets whether this window should receive focus on
2631      * subsequently being shown (with a call to {@link #setVisible setVisible(true)}),
2632      * or being moved to the front (with a call to {@link #toFront}).
2633      * <p>
2634      * Note that {@link #setVisible setVisible(true)} may be called indirectly
2635      * (e.g. when showing an owner of the window makes the window to be shown).
2636      * {@link #toFront} may also be called indirectly (e.g. when
2637      * {@link #setVisible setVisible(true)} is called on already visible window).
2638      * In all such cases this property takes effect as well.
2639      * <p>
2640      * The value of the property is not inherited by owned windows.
2641      *
2642      * @param autoRequestFocus whether this window should be focused on
2643      *        subsequently being shown or being moved to the front
2644      * @see #isAutoRequestFocus
2645      * @see #isFocusableWindow
2646      * @see #setVisible
2647      * @see #toFront
2648      * @since 1.7
2649      */
setAutoRequestFocus(boolean autoRequestFocus)2650     public void setAutoRequestFocus(boolean autoRequestFocus) {
2651         this.autoRequestFocus = autoRequestFocus;
2652     }
2653 
2654     /**
2655      * Returns whether this window should receive focus on subsequently being shown
2656      * (with a call to {@link #setVisible setVisible(true)}), or being moved to the front
2657      * (with a call to {@link #toFront}).
2658      * <p>
2659      * By default, the window has {@code autoRequestFocus} value of {@code true}.
2660      *
2661      * @return {@code autoRequestFocus} value
2662      * @see #setAutoRequestFocus
2663      * @since 1.7
2664      */
isAutoRequestFocus()2665     public boolean isAutoRequestFocus() {
2666         return autoRequestFocus;
2667     }
2668 
2669     /**
2670      * Adds a PropertyChangeListener to the listener list. The listener is
2671      * registered for all bound properties of this class, including the
2672      * following:
2673      * <ul>
2674      *    <li>this Window's font ("font")</li>
2675      *    <li>this Window's background color ("background")</li>
2676      *    <li>this Window's foreground color ("foreground")</li>
2677      *    <li>this Window's focusability ("focusable")</li>
2678      *    <li>this Window's focus traversal keys enabled state
2679      *        ("focusTraversalKeysEnabled")</li>
2680      *    <li>this Window's Set of FORWARD_TRAVERSAL_KEYS
2681      *        ("forwardFocusTraversalKeys")</li>
2682      *    <li>this Window's Set of BACKWARD_TRAVERSAL_KEYS
2683      *        ("backwardFocusTraversalKeys")</li>
2684      *    <li>this Window's Set of UP_CYCLE_TRAVERSAL_KEYS
2685      *        ("upCycleFocusTraversalKeys")</li>
2686      *    <li>this Window's Set of DOWN_CYCLE_TRAVERSAL_KEYS
2687      *        ("downCycleFocusTraversalKeys")</li>
2688      *    <li>this Window's focus traversal policy ("focusTraversalPolicy")
2689      *        </li>
2690      *    <li>this Window's focusable Window state ("focusableWindowState")
2691      *        </li>
2692      *    <li>this Window's always-on-top state("alwaysOnTop")</li>
2693      * </ul>
2694      * Note that if this Window is inheriting a bound property, then no
2695      * event will be fired in response to a change in the inherited property.
2696      * <p>
2697      * If listener is null, no exception is thrown and no action is performed.
2698      *
2699      * @param    listener  the PropertyChangeListener to be added
2700      *
2701      * @see Component#removePropertyChangeListener
2702      * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
2703      */
addPropertyChangeListener(PropertyChangeListener listener)2704     public void addPropertyChangeListener(PropertyChangeListener listener) {
2705         super.addPropertyChangeListener(listener);
2706     }
2707 
2708     /**
2709      * Adds a PropertyChangeListener to the listener list for a specific
2710      * property. The specified property may be user-defined, or one of the
2711      * following:
2712      * <ul>
2713      *    <li>this Window's font ("font")</li>
2714      *    <li>this Window's background color ("background")</li>
2715      *    <li>this Window's foreground color ("foreground")</li>
2716      *    <li>this Window's focusability ("focusable")</li>
2717      *    <li>this Window's focus traversal keys enabled state
2718      *        ("focusTraversalKeysEnabled")</li>
2719      *    <li>this Window's Set of FORWARD_TRAVERSAL_KEYS
2720      *        ("forwardFocusTraversalKeys")</li>
2721      *    <li>this Window's Set of BACKWARD_TRAVERSAL_KEYS
2722      *        ("backwardFocusTraversalKeys")</li>
2723      *    <li>this Window's Set of UP_CYCLE_TRAVERSAL_KEYS
2724      *        ("upCycleFocusTraversalKeys")</li>
2725      *    <li>this Window's Set of DOWN_CYCLE_TRAVERSAL_KEYS
2726      *        ("downCycleFocusTraversalKeys")</li>
2727      *    <li>this Window's focus traversal policy ("focusTraversalPolicy")
2728      *        </li>
2729      *    <li>this Window's focusable Window state ("focusableWindowState")
2730      *        </li>
2731      *    <li>this Window's always-on-top state("alwaysOnTop")</li>
2732      * </ul>
2733      * Note that if this Window is inheriting a bound property, then no
2734      * event will be fired in response to a change in the inherited property.
2735      * <p>
2736      * If listener is null, no exception is thrown and no action is performed.
2737      *
2738      * @param propertyName one of the property names listed above
2739      * @param listener the PropertyChangeListener to be added
2740      *
2741      * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
2742      * @see Component#removePropertyChangeListener
2743      */
addPropertyChangeListener(String propertyName, PropertyChangeListener listener)2744     public void addPropertyChangeListener(String propertyName,
2745                                           PropertyChangeListener listener) {
2746         super.addPropertyChangeListener(propertyName, listener);
2747     }
2748 
2749     /**
2750      * Indicates if this container is a validate root.
2751      * <p>
2752      * {@code Window} objects are the validate roots, and, therefore, they
2753      * override this method to return {@code true}.
2754      *
2755      * @return {@code true}
2756      * @since 1.7
2757      * @see java.awt.Container#isValidateRoot
2758      */
2759     @Override
isValidateRoot()2760     public boolean isValidateRoot() {
2761         return true;
2762     }
2763 
2764     /**
2765      * Dispatches an event to this window or one of its sub components.
2766      * @param e the event
2767      */
dispatchEventImpl(AWTEvent e)2768     void dispatchEventImpl(AWTEvent e) {
2769         if (e.getID() == ComponentEvent.COMPONENT_RESIZED) {
2770             invalidate();
2771             validate();
2772         }
2773         super.dispatchEventImpl(e);
2774     }
2775 
2776     /**
2777      * @deprecated As of JDK version 1.1
2778      * replaced by {@code dispatchEvent(AWTEvent)}.
2779      */
2780     @Deprecated
postEvent(Event e)2781     public boolean postEvent(Event e) {
2782         if (handleEvent(e)) {
2783             e.consume();
2784             return true;
2785         }
2786         return false;
2787     }
2788 
2789     /**
2790      * Checks if this Window is showing on screen.
2791      * @see Component#setVisible
2792     */
isShowing()2793     public boolean isShowing() {
2794         return visible;
2795     }
2796 
isDisposing()2797     boolean isDisposing() {
2798         return disposing;
2799     }
2800 
2801     /**
2802      * @deprecated As of J2SE 1.4, replaced by
2803      * {@link Component#applyComponentOrientation Component.applyComponentOrientation}.
2804      * @param rb the resource bundle
2805      */
2806     @Deprecated
applyResourceBundle(ResourceBundle rb)2807     public void applyResourceBundle(ResourceBundle rb) {
2808         applyComponentOrientation(ComponentOrientation.getOrientation(rb));
2809     }
2810 
2811     /**
2812      * @deprecated As of J2SE 1.4, replaced by
2813      * {@link Component#applyComponentOrientation Component.applyComponentOrientation}.
2814      * @param rbName the resource name
2815      */
2816     @Deprecated
applyResourceBundle(String rbName)2817     public void applyResourceBundle(String rbName) {
2818         // Use the unnamed module from the TCCL or system class loader.
2819         ClassLoader cl = Thread.currentThread().getContextClassLoader();
2820         if (cl == null) {
2821             cl = ClassLoader.getSystemClassLoader();
2822         }
2823         applyResourceBundle(ResourceBundle.getBundle(rbName, cl.getUnnamedModule()));
2824     }
2825 
2826    /*
2827     * Support for tracking all windows owned by this window
2828     */
addOwnedWindow(WeakReference<Window> weakWindow)2829     void addOwnedWindow(WeakReference<Window> weakWindow) {
2830         if (weakWindow != null) {
2831             synchronized(ownedWindowList) {
2832                 // this if statement should really be an assert, but we don't
2833                 // have asserts...
2834                 if (!ownedWindowList.contains(weakWindow)) {
2835                     ownedWindowList.addElement(weakWindow);
2836                 }
2837             }
2838         }
2839     }
2840 
removeOwnedWindow(WeakReference<Window> weakWindow)2841     void removeOwnedWindow(WeakReference<Window> weakWindow) {
2842         if (weakWindow != null) {
2843             // synchronized block not required since removeElement is
2844             // already synchronized
2845             ownedWindowList.removeElement(weakWindow);
2846         }
2847     }
2848 
connectOwnedWindow(Window child)2849     void connectOwnedWindow(Window child) {
2850         child.parent = this;
2851         addOwnedWindow(child.weakThis);
2852         child.disposerRecord.updateOwner();
2853     }
2854 
addToWindowList()2855     private void addToWindowList() {
2856         synchronized (Window.class) {
2857             @SuppressWarnings("unchecked")
2858             Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)appContext.get(Window.class);
2859             if (windowList == null) {
2860                 windowList = new Vector<WeakReference<Window>>();
2861                 appContext.put(Window.class, windowList);
2862             }
2863             windowList.add(weakThis);
2864         }
2865     }
2866 
removeFromWindowList(AppContext context, WeakReference<Window> weakThis)2867     private static void removeFromWindowList(AppContext context, WeakReference<Window> weakThis) {
2868         synchronized (Window.class) {
2869             @SuppressWarnings("unchecked")
2870             Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)context.get(Window.class);
2871             if (windowList != null) {
2872                 windowList.remove(weakThis);
2873             }
2874         }
2875     }
2876 
removeFromWindowList()2877     private void removeFromWindowList() {
2878         removeFromWindowList(appContext, weakThis);
2879     }
2880 
2881     /**
2882      * Window type.
2883      *
2884      * Synchronization: ObjectLock
2885      */
2886     private Type type = Type.NORMAL;
2887 
2888     /**
2889      * Sets the type of the window.
2890      *
2891      * This method can only be called while the window is not displayable.
2892      *
2893      * @param  type the window type
2894      * @throws IllegalComponentStateException if the window
2895      *         is displayable.
2896      * @throws IllegalArgumentException if the type is {@code null}
2897      * @see    Component#isDisplayable
2898      * @see    #getType
2899      * @since 1.7
2900      */
setType(Type type)2901     public void setType(Type type) {
2902         if (type == null) {
2903             throw new IllegalArgumentException("type should not be null.");
2904         }
2905         synchronized (getTreeLock()) {
2906             if (isDisplayable()) {
2907                 throw new IllegalComponentStateException(
2908                         "The window is displayable.");
2909             }
2910             synchronized (getObjectLock()) {
2911                 this.type = type;
2912             }
2913         }
2914     }
2915 
2916     /**
2917      * Returns the type of the window.
2918      *
2919      * @return the type of the window
2920      * @see   #setType
2921      * @since 1.7
2922      */
getType()2923     public Type getType() {
2924         synchronized (getObjectLock()) {
2925             return type;
2926         }
2927     }
2928 
2929     /**
2930      * The window serialized data version.
2931      *
2932      * @serial
2933      */
2934     private int windowSerializedDataVersion = 2;
2935 
2936     /**
2937      * Writes default serializable fields to stream.  Writes
2938      * a list of serializable {@code WindowListener}s and
2939      * {@code WindowFocusListener}s as optional data.
2940      * Writes a list of child windows as optional data.
2941      * Writes a list of icon images as optional data
2942      *
2943      * @param  s the {@code ObjectOutputStream} to write
2944      * @throws IOException if an I/O error occurs
2945      * @serialData {@code null} terminated sequence of
2946      *    0 or more pairs; the pair consists of a {@code String}
2947      *    and {@code Object}; the {@code String}
2948      *    indicates the type of object and is one of the following:
2949      *    {@code windowListenerK} indicating a
2950      *      {@code WindowListener} object;
2951      *    {@code windowFocusWindowK} indicating a
2952      *      {@code WindowFocusListener} object;
2953      *    {@code ownedWindowK} indicating a child
2954      *      {@code Window} object
2955      *
2956      * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
2957      * @see Component#windowListenerK
2958      * @see Component#windowFocusListenerK
2959      * @see Component#ownedWindowK
2960      * @see #readObject(ObjectInputStream)
2961      */
writeObject(ObjectOutputStream s)2962     private void writeObject(ObjectOutputStream s) throws IOException {
2963         synchronized (this) {
2964             // Update old focusMgr fields so that our object stream can be read
2965             // by previous releases
2966             focusMgr = new FocusManager();
2967             focusMgr.focusRoot = this;
2968             focusMgr.focusOwner = getMostRecentFocusOwner();
2969 
2970             s.defaultWriteObject();
2971 
2972             // Clear fields so that we don't keep extra references around
2973             focusMgr = null;
2974 
2975             AWTEventMulticaster.save(s, windowListenerK, windowListener);
2976             AWTEventMulticaster.save(s, windowFocusListenerK, windowFocusListener);
2977             AWTEventMulticaster.save(s, windowStateListenerK, windowStateListener);
2978         }
2979 
2980         s.writeObject(null);
2981 
2982         synchronized (ownedWindowList) {
2983             for (int i = 0; i < ownedWindowList.size(); i++) {
2984                 Window child = ownedWindowList.elementAt(i).get();
2985                 if (child != null) {
2986                     s.writeObject(ownedWindowK);
2987                     s.writeObject(child);
2988                 }
2989             }
2990         }
2991         s.writeObject(null);
2992 
2993         //write icon array
2994         if (icons != null) {
2995             for (Image i : icons) {
2996                 if (i instanceof Serializable) {
2997                     s.writeObject(i);
2998                 }
2999             }
3000         }
3001         s.writeObject(null);
3002     }
3003 
3004     //
3005     // Part of deserialization procedure to be called before
3006     // user's code.
3007     //
initDeserializedWindow()3008     private void initDeserializedWindow() {
3009         setWarningString();
3010         inputContextLock = new Object();
3011 
3012         // Deserialized Windows are not yet visible.
3013         visible = false;
3014 
3015         weakThis = new WeakReference<>(this);
3016 
3017         anchor = new Object();
3018         disposerRecord = new WindowDisposerRecord(appContext, this);
3019         sun.java2d.Disposer.addRecord(anchor, disposerRecord);
3020 
3021         addToWindowList();
3022         initGC(null);
3023         ownedWindowList = new Vector<>();
3024     }
3025 
deserializeResources(ObjectInputStream s)3026     private void deserializeResources(ObjectInputStream s)
3027         throws ClassNotFoundException, IOException, HeadlessException {
3028 
3029             if (windowSerializedDataVersion < 2) {
3030                 // Translate old-style focus tracking to new model. For 1.4 and
3031                 // later releases, we'll rely on the Window's initial focusable
3032                 // Component.
3033                 if (focusMgr != null) {
3034                     if (focusMgr.focusOwner != null) {
3035                         KeyboardFocusManager.
3036                             setMostRecentFocusOwner(this, focusMgr.focusOwner);
3037                     }
3038                 }
3039 
3040                 // This field is non-transient and relies on default serialization.
3041                 // However, the default value is insufficient, so we need to set
3042                 // it explicitly for object data streams prior to 1.4.
3043                 focusableWindowState = true;
3044 
3045 
3046             }
3047 
3048         Object keyOrNull;
3049         while(null != (keyOrNull = s.readObject())) {
3050             String key = ((String)keyOrNull).intern();
3051 
3052             if (windowListenerK == key) {
3053                 addWindowListener((WindowListener)(s.readObject()));
3054             } else if (windowFocusListenerK == key) {
3055                 addWindowFocusListener((WindowFocusListener)(s.readObject()));
3056             } else if (windowStateListenerK == key) {
3057                 addWindowStateListener((WindowStateListener)(s.readObject()));
3058             } else // skip value for unrecognized key
3059                 s.readObject();
3060         }
3061 
3062         try {
3063             while (null != (keyOrNull = s.readObject())) {
3064                 String key = ((String)keyOrNull).intern();
3065 
3066                 if (ownedWindowK == key)
3067                     connectOwnedWindow((Window) s.readObject());
3068 
3069                 else // skip value for unrecognized key
3070                     s.readObject();
3071             }
3072 
3073             //read icons
3074             Object obj = s.readObject(); //Throws OptionalDataException
3075                                          //for pre1.6 objects.
3076             icons = new ArrayList<Image>(); //Frame.readObject() assumes
3077                                             //pre1.6 version if icons is null.
3078             while (obj != null) {
3079                 if (obj instanceof Image) {
3080                     icons.add((Image)obj);
3081                 }
3082                 obj = s.readObject();
3083             }
3084         }
3085         catch (OptionalDataException e) {
3086             // 1.1 serialized form
3087             // ownedWindowList will be updated by Frame.readObject
3088         }
3089 
3090     }
3091 
3092     /**
3093      * Reads the {@code ObjectInputStream} and an optional
3094      * list of listeners to receive various events fired by
3095      * the component; also reads a list of
3096      * (possibly {@code null}) child windows.
3097      * Unrecognized keys or values will be ignored.
3098      *
3099      * @param  s the {@code ObjectInputStream} to read
3100      * @throws ClassNotFoundException if the class of a serialized object could
3101      *         not be found
3102      * @throws IOException if an I/O error occurs
3103      * @throws HeadlessException if {@code GraphicsEnvironment.isHeadless()}
3104      *         returns {@code true}
3105      * @see java.awt.GraphicsEnvironment#isHeadless
3106      * @see #writeObject
3107      */
readObject(ObjectInputStream s)3108     private void readObject(ObjectInputStream s)
3109       throws ClassNotFoundException, IOException, HeadlessException
3110     {
3111          GraphicsEnvironment.checkHeadless();
3112          initDeserializedWindow();
3113          ObjectInputStream.GetField f = s.readFields();
3114 
3115          syncLWRequests = f.get("syncLWRequests", systemSyncLWRequests);
3116          state = f.get("state", 0);
3117          focusableWindowState = f.get("focusableWindowState", true);
3118          windowSerializedDataVersion = f.get("windowSerializedDataVersion", 1);
3119          locationByPlatform = f.get("locationByPlatform", locationByPlatformProp);
3120          // Note: 1.4 (or later) doesn't use focusMgr
3121          focusMgr = (FocusManager)f.get("focusMgr", null);
3122          Dialog.ModalExclusionType et = (Dialog.ModalExclusionType)
3123              f.get("modalExclusionType", Dialog.ModalExclusionType.NO_EXCLUDE);
3124          setModalExclusionType(et); // since 6.0
3125          boolean aot = f.get("alwaysOnTop", false);
3126          if(aot) {
3127              setAlwaysOnTop(aot); // since 1.5; subject to permission check
3128          }
3129          shape = (Shape)f.get("shape", null);
3130          opacity = (Float)f.get("opacity", 1.0f);
3131 
3132          this.securityWarningWidth = 0;
3133          this.securityWarningHeight = 0;
3134 
3135          deserializeResources(s);
3136     }
3137 
3138     /*
3139      * --- Accessibility Support ---
3140      *
3141      */
3142 
3143     /**
3144      * Gets the AccessibleContext associated with this Window.
3145      * For windows, the AccessibleContext takes the form of an
3146      * AccessibleAWTWindow.
3147      * A new AccessibleAWTWindow instance is created if necessary.
3148      *
3149      * @return an AccessibleAWTWindow that serves as the
3150      *         AccessibleContext of this Window
3151      * @since 1.3
3152      */
getAccessibleContext()3153     public AccessibleContext getAccessibleContext() {
3154         if (accessibleContext == null) {
3155             accessibleContext = new AccessibleAWTWindow();
3156         }
3157         return accessibleContext;
3158     }
3159 
3160     /**
3161      * This class implements accessibility support for the
3162      * {@code Window} class.  It provides an implementation of the
3163      * Java Accessibility API appropriate to window user-interface elements.
3164      * @since 1.3
3165      */
3166     protected class AccessibleAWTWindow extends AccessibleAWTContainer
3167     {
3168         /*
3169          * JDK 1.3 serialVersionUID
3170          */
3171         private static final long serialVersionUID = 4215068635060671780L;
3172 
3173         /**
3174          * Constructs an {@code AccessibleAWTWindow}.
3175          */
AccessibleAWTWindow()3176         protected AccessibleAWTWindow() {}
3177 
3178         /**
3179          * Get the role of this object.
3180          *
3181          * @return an instance of AccessibleRole describing the role of the
3182          * object
3183          * @see javax.accessibility.AccessibleRole
3184          */
getAccessibleRole()3185         public AccessibleRole getAccessibleRole() {
3186             return AccessibleRole.WINDOW;
3187         }
3188 
3189         /**
3190          * Get the state of this object.
3191          *
3192          * @return an instance of AccessibleStateSet containing the current
3193          * state set of the object
3194          * @see javax.accessibility.AccessibleState
3195          */
getAccessibleStateSet()3196         public AccessibleStateSet getAccessibleStateSet() {
3197             AccessibleStateSet states = super.getAccessibleStateSet();
3198             if (getFocusOwner() != null) {
3199                 states.add(AccessibleState.ACTIVE);
3200             }
3201             return states;
3202         }
3203 
3204     } // inner class AccessibleAWTWindow
3205 
3206     @Override
setGraphicsConfiguration(GraphicsConfiguration gc)3207     void setGraphicsConfiguration(GraphicsConfiguration gc) {
3208         if (gc == null) {
3209             gc = GraphicsEnvironment.
3210                     getLocalGraphicsEnvironment().
3211                     getDefaultScreenDevice().
3212                     getDefaultConfiguration();
3213         }
3214         synchronized (getTreeLock()) {
3215             super.setGraphicsConfiguration(gc);
3216             if (log.isLoggable(PlatformLogger.Level.FINER)) {
3217                 log.finer("+ Window.setGraphicsConfiguration(): new GC is \n+ " + getGraphicsConfiguration_NoClientCode() + "\n+ this is " + this);
3218             }
3219         }
3220     }
3221 
3222     /**
3223      * Sets the location of the window relative to the specified
3224      * component according to the following scenarios.
3225      * <p>
3226      * The target screen mentioned below is a screen to which
3227      * the window should be placed after the setLocationRelativeTo
3228      * method is called.
3229      * <ul>
3230      * <li>If the component is {@code null}, or the {@code
3231      * GraphicsConfiguration} associated with this component is
3232      * {@code null}, the window is placed in the center of the
3233      * screen. The center point can be obtained with the {@link
3234      * GraphicsEnvironment#getCenterPoint
3235      * GraphicsEnvironment.getCenterPoint} method.
3236      * <li>If the component is not {@code null}, but it is not
3237      * currently showing, the window is placed in the center of
3238      * the target screen defined by the {@code
3239      * GraphicsConfiguration} associated with this component.
3240      * <li>If the component is not {@code null} and is shown on
3241      * the screen, then the window is located in such a way that
3242      * the center of the window coincides with the center of the
3243      * component.
3244      * </ul>
3245      * <p>
3246      * If the screens configuration does not allow the window to
3247      * be moved from one screen to another, then the window is
3248      * only placed at the location determined according to the
3249      * above conditions and its {@code GraphicsConfiguration} is
3250      * not changed.
3251      * <p>
3252      * <b>Note</b>: If the lower edge of the window is out of the screen,
3253      * then the window is placed to the side of the {@code Component}
3254      * that is closest to the center of the screen. So if the
3255      * component is on the right part of the screen, the window
3256      * is placed to its left, and vice versa.
3257      * <p>
3258      * If after the window location has been calculated, the upper,
3259      * left, or right edge of the window is out of the screen,
3260      * then the window is located in such a way that the upper,
3261      * left, or right edge of the window coincides with the
3262      * corresponding edge of the screen. If both left and right
3263      * edges of the window are out of the screen, the window is
3264      * placed at the left side of the screen. The similar placement
3265      * will occur if both top and bottom edges are out of the screen.
3266      * In that case, the window is placed at the top side of the screen.
3267      * <p>
3268      * The method changes the geometry-related data. Therefore,
3269      * the native windowing system may ignore such requests, or it may modify
3270      * the requested data, so that the {@code Window} object is placed and sized
3271      * in a way that corresponds closely to the desktop settings.
3272      *
3273      * @param c  the component in relation to which the window's location
3274      *           is determined
3275      * @see java.awt.GraphicsEnvironment#getCenterPoint
3276      * @since 1.4
3277      */
setLocationRelativeTo(Component c)3278     public void setLocationRelativeTo(Component c) {
3279         // target location
3280         int dx = 0, dy = 0;
3281         // target GC
3282         GraphicsConfiguration gc = getGraphicsConfiguration_NoClientCode();
3283         Rectangle gcBounds = gc.getBounds();
3284 
3285         Dimension windowSize = getSize();
3286 
3287         // search a top-level of c
3288         Window componentWindow = SunToolkit.getContainingWindow(c);
3289         if ((c == null) || (componentWindow == null)) {
3290             GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
3291             gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
3292             gcBounds = gc.getBounds();
3293             Point centerPoint = ge.getCenterPoint();
3294             dx = centerPoint.x - windowSize.width / 2;
3295             dy = centerPoint.y - windowSize.height / 2;
3296         } else if (!c.isShowing()) {
3297             gc = componentWindow.getGraphicsConfiguration();
3298             gcBounds = gc.getBounds();
3299             dx = gcBounds.x + (gcBounds.width - windowSize.width) / 2;
3300             dy = gcBounds.y + (gcBounds.height - windowSize.height) / 2;
3301         } else {
3302             gc = componentWindow.getGraphicsConfiguration();
3303             gcBounds = gc.getBounds();
3304             Dimension compSize = c.getSize();
3305             Point compLocation = c.getLocationOnScreen();
3306             dx = compLocation.x + ((compSize.width - windowSize.width) / 2);
3307             dy = compLocation.y + ((compSize.height - windowSize.height) / 2);
3308 
3309             // Adjust for bottom edge being offscreen
3310             if (dy + windowSize.height > gcBounds.y + gcBounds.height) {
3311                 dy = gcBounds.y + gcBounds.height - windowSize.height;
3312                 if (compLocation.x - gcBounds.x + compSize.width / 2 < gcBounds.width / 2) {
3313                     dx = compLocation.x + compSize.width;
3314                 } else {
3315                     dx = compLocation.x - windowSize.width;
3316                 }
3317             }
3318         }
3319 
3320         // Avoid being placed off the edge of the screen:
3321         // bottom
3322         if (dy + windowSize.height > gcBounds.y + gcBounds.height) {
3323             dy = gcBounds.y + gcBounds.height - windowSize.height;
3324         }
3325         // top
3326         if (dy < gcBounds.y) {
3327             dy = gcBounds.y;
3328         }
3329         // right
3330         if (dx + windowSize.width > gcBounds.x + gcBounds.width) {
3331             dx = gcBounds.x + gcBounds.width - windowSize.width;
3332         }
3333         // left
3334         if (dx < gcBounds.x) {
3335             dx = gcBounds.x;
3336         }
3337 
3338         setLocation(dx, dy);
3339     }
3340 
3341     /**
3342      * Overridden from Component.  Top-level Windows should not propagate a
3343      * MouseWheelEvent beyond themselves into their owning Windows.
3344      */
deliverMouseWheelToAncestor(MouseWheelEvent e)3345     void deliverMouseWheelToAncestor(MouseWheelEvent e) {}
3346 
3347     /**
3348      * Overridden from Component.  Top-level Windows don't dispatch to ancestors
3349      */
dispatchMouseWheelToAncestor(MouseWheelEvent e)3350     boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {return false;}
3351 
3352     /**
3353      * Creates a new strategy for multi-buffering on this component.
3354      * Multi-buffering is useful for rendering performance.  This method
3355      * attempts to create the best strategy available with the number of
3356      * buffers supplied.  It will always create a {@code BufferStrategy}
3357      * with that number of buffers.
3358      * A page-flipping strategy is attempted first, then a blitting strategy
3359      * using accelerated buffers.  Finally, an unaccelerated blitting
3360      * strategy is used.
3361      * <p>
3362      * Each time this method is called,
3363      * the existing buffer strategy for this component is discarded.
3364      * @param numBuffers number of buffers to create
3365      * @exception IllegalArgumentException if numBuffers is less than 1.
3366      * @exception IllegalStateException if the component is not displayable
3367      * @see #isDisplayable
3368      * @see #getBufferStrategy
3369      * @since 1.4
3370      */
createBufferStrategy(int numBuffers)3371     public void createBufferStrategy(int numBuffers) {
3372         super.createBufferStrategy(numBuffers);
3373     }
3374 
3375     /**
3376      * Creates a new strategy for multi-buffering on this component with the
3377      * required buffer capabilities.  This is useful, for example, if only
3378      * accelerated memory or page flipping is desired (as specified by the
3379      * buffer capabilities).
3380      * <p>
3381      * Each time this method
3382      * is called, the existing buffer strategy for this component is discarded.
3383      * @param numBuffers number of buffers to create, including the front buffer
3384      * @param caps the required capabilities for creating the buffer strategy;
3385      * cannot be {@code null}
3386      * @exception AWTException if the capabilities supplied could not be
3387      * supported or met; this may happen, for example, if there is not enough
3388      * accelerated memory currently available, or if page flipping is specified
3389      * but not possible.
3390      * @exception IllegalArgumentException if numBuffers is less than 1, or if
3391      * caps is {@code null}
3392      * @see #getBufferStrategy
3393      * @since 1.4
3394      */
createBufferStrategy(int numBuffers, BufferCapabilities caps)3395     public void createBufferStrategy(int numBuffers,
3396         BufferCapabilities caps) throws AWTException {
3397         super.createBufferStrategy(numBuffers, caps);
3398     }
3399 
3400     /**
3401      * Returns the {@code BufferStrategy} used by this component.  This
3402      * method will return null if a {@code BufferStrategy} has not yet
3403      * been created or has been disposed.
3404      *
3405      * @return the buffer strategy used by this component
3406      * @see #createBufferStrategy
3407      * @since 1.4
3408      */
getBufferStrategy()3409     public BufferStrategy getBufferStrategy() {
3410         return super.getBufferStrategy();
3411     }
3412 
getTemporaryLostComponent()3413     Component getTemporaryLostComponent() {
3414         return temporaryLostComponent;
3415     }
setTemporaryLostComponent(Component component)3416     Component setTemporaryLostComponent(Component component) {
3417         Component previousComp = temporaryLostComponent;
3418         // Check that "component" is an acceptable focus owner and don't store it otherwise
3419         // - or later we will have problems with opposite while handling  WINDOW_GAINED_FOCUS
3420         if (component == null || component.canBeFocusOwner()) {
3421             temporaryLostComponent = component;
3422         } else {
3423             temporaryLostComponent = null;
3424         }
3425         return previousComp;
3426     }
3427 
3428     /**
3429      * Checks whether this window can contain focus owner.
3430      * Verifies that it is focusable and as container it can container focus owner.
3431      * @since 1.5
3432      */
canContainFocusOwner(Component focusOwnerCandidate)3433     boolean canContainFocusOwner(Component focusOwnerCandidate) {
3434         return super.canContainFocusOwner(focusOwnerCandidate) && isFocusableWindow();
3435     }
3436 
3437     /**
3438      * {@code true} if this Window should appear at the default location,
3439      * {@code false} if at the current location.
3440      */
3441     private volatile boolean locationByPlatform = locationByPlatformProp;
3442 
3443 
3444     /**
3445      * Sets whether this Window should appear at the default location for the
3446      * native windowing system or at the current location (returned by
3447      * {@code getLocation}) the next time the Window is made visible.
3448      * This behavior resembles a native window shown without programmatically
3449      * setting its location.  Most windowing systems cascade windows if their
3450      * locations are not explicitly set. The actual location is determined once the
3451      * window is shown on the screen.
3452      * <p>
3453      * This behavior can also be enabled by setting the System Property
3454      * "java.awt.Window.locationByPlatform" to "true", though calls to this method
3455      * take precedence.
3456      * <p>
3457      * Calls to {@code setVisible}, {@code setLocation} and
3458      * {@code setBounds} after calling {@code setLocationByPlatform} clear
3459      * this property of the Window.
3460      * <p>
3461      * For example, after the following code is executed:
3462      * <pre>
3463      * setLocationByPlatform(true);
3464      * setVisible(true);
3465      * boolean flag = isLocationByPlatform();
3466      * </pre>
3467      * The window will be shown at platform's default location and
3468      * {@code flag} will be {@code false}.
3469      * <p>
3470      * In the following sample:
3471      * <pre>
3472      * setLocationByPlatform(true);
3473      * setLocation(10, 10);
3474      * boolean flag = isLocationByPlatform();
3475      * setVisible(true);
3476      * </pre>
3477      * The window will be shown at (10, 10) and {@code flag} will be
3478      * {@code false}.
3479      *
3480      * @param locationByPlatform {@code true} if this Window should appear
3481      *        at the default location, {@code false} if at the current location
3482      * @throws IllegalComponentStateException if the window
3483      *         is showing on screen and locationByPlatform is {@code true}.
3484      * @see #setLocation
3485      * @see #isShowing
3486      * @see #setVisible
3487      * @see #isLocationByPlatform
3488      * @see java.lang.System#getProperty(String)
3489      * @since 1.5
3490      */
setLocationByPlatform(boolean locationByPlatform)3491     public void setLocationByPlatform(boolean locationByPlatform) {
3492         synchronized (getTreeLock()) {
3493             if (locationByPlatform && isShowing()) {
3494                 throw new IllegalComponentStateException("The window is showing on screen.");
3495             }
3496             this.locationByPlatform = locationByPlatform;
3497         }
3498     }
3499 
3500     /**
3501      * Returns {@code true} if this Window will appear at the default location
3502      * for the native windowing system the next time this Window is made visible.
3503      * This method always returns {@code false} if the Window is showing on the
3504      * screen.
3505      *
3506      * @return whether this Window will appear at the default location
3507      * @see #setLocationByPlatform
3508      * @see #isShowing
3509      * @since 1.5
3510      */
isLocationByPlatform()3511     public boolean isLocationByPlatform() {
3512         return locationByPlatform;
3513     }
3514 
3515     /**
3516      * {@inheritDoc}
3517      * <p>
3518      * The {@code width} or {@code height} values
3519      * are automatically enlarged if either is less than
3520      * the minimum size as specified by previous call to
3521      * {@code setMinimumSize}.
3522      * <p>
3523      * The method changes the geometry-related data. Therefore,
3524      * the native windowing system may ignore such requests, or it may modify
3525      * the requested data, so that the {@code Window} object is placed and sized
3526      * in a way that corresponds closely to the desktop settings.
3527      *
3528      * @see #getBounds
3529      * @see #setLocation(int, int)
3530      * @see #setLocation(Point)
3531      * @see #setSize(int, int)
3532      * @see #setSize(Dimension)
3533      * @see #setMinimumSize
3534      * @see #setLocationByPlatform
3535      * @see #isLocationByPlatform
3536      * @since 1.6
3537      */
setBounds(int x, int y, int width, int height)3538     public void setBounds(int x, int y, int width, int height) {
3539         synchronized (getTreeLock()) {
3540             if (getBoundsOp() == ComponentPeer.SET_LOCATION ||
3541                 getBoundsOp() == ComponentPeer.SET_BOUNDS)
3542             {
3543                 locationByPlatform = false;
3544             }
3545             super.setBounds(x, y, width, height);
3546         }
3547     }
3548 
3549     /**
3550      * {@inheritDoc}
3551      * <p>
3552      * The {@code r.width} or {@code r.height} values
3553      * will be automatically enlarged if either is less than
3554      * the minimum size as specified by previous call to
3555      * {@code setMinimumSize}.
3556      * <p>
3557      * The method changes the geometry-related data. Therefore,
3558      * the native windowing system may ignore such requests, or it may modify
3559      * the requested data, so that the {@code Window} object is placed and sized
3560      * in a way that corresponds closely to the desktop settings.
3561      *
3562      * @see #getBounds
3563      * @see #setLocation(int, int)
3564      * @see #setLocation(Point)
3565      * @see #setSize(int, int)
3566      * @see #setSize(Dimension)
3567      * @see #setMinimumSize
3568      * @see #setLocationByPlatform
3569      * @see #isLocationByPlatform
3570      * @since 1.6
3571      */
setBounds(Rectangle r)3572     public void setBounds(Rectangle r) {
3573         setBounds(r.x, r.y, r.width, r.height);
3574     }
3575 
3576     /**
3577      * Determines whether this component will be displayed on the screen.
3578      * @return {@code true} if the component and all of its ancestors
3579      *          until a toplevel window are visible, {@code false} otherwise
3580      */
isRecursivelyVisible()3581     boolean isRecursivelyVisible() {
3582         // 5079694 fix: for a toplevel to be displayed, its parent doesn't have to be visible.
3583         // We're overriding isRecursivelyVisible to implement this policy.
3584         return visible;
3585     }
3586 
3587 
3588     // ******************** SHAPES & TRANSPARENCY CODE ********************
3589 
3590     /**
3591      * Returns the opacity of the window.
3592      *
3593      * @return the opacity of the window
3594      *
3595      * @see Window#setOpacity(float)
3596      * @see GraphicsDevice.WindowTranslucency
3597      *
3598      * @since 1.7
3599      */
getOpacity()3600     public float getOpacity() {
3601         return opacity;
3602     }
3603 
3604     /**
3605      * Sets the opacity of the window.
3606      * <p>
3607      * The opacity value is in the range [0..1]. Note that setting the opacity
3608      * level of 0 may or may not disable the mouse event handling on this
3609      * window. This is a platform-dependent behavior.
3610      * <p>
3611      * The following conditions must be met in order to set the opacity value
3612      * less than {@code 1.0f}:
3613      * <ul>
3614      * <li>The {@link GraphicsDevice.WindowTranslucency#TRANSLUCENT TRANSLUCENT}
3615      * translucency must be supported by the underlying system
3616      * <li>The window must be undecorated (see {@link Frame#setUndecorated}
3617      * and {@link Dialog#setUndecorated})
3618      * <li>The window must not be in full-screen mode (see {@link
3619      * GraphicsDevice#setFullScreenWindow(Window)})
3620      * </ul>
3621      * <p>
3622      * If the requested opacity value is less than {@code 1.0f}, and any of the
3623      * above conditions are not met, the window opacity will not change,
3624      * and the {@code IllegalComponentStateException} will be thrown.
3625      * <p>
3626      * The translucency levels of individual pixels may also be effected by the
3627      * alpha component of their color (see {@link Window#setBackground(Color)}) and the
3628      * current shape of this window (see {@link #setShape(Shape)}).
3629      *
3630      * @param opacity the opacity level to set to the window
3631      *
3632      * @throws IllegalArgumentException if the opacity is out of the range
3633      *     [0..1]
3634      * @throws IllegalComponentStateException if the window is decorated and
3635      *     the opacity is less than {@code 1.0f}
3636      * @throws IllegalComponentStateException if the window is in full screen
3637      *     mode, and the opacity is less than {@code 1.0f}
3638      * @throws UnsupportedOperationException if the {@code
3639      *     GraphicsDevice.WindowTranslucency#TRANSLUCENT TRANSLUCENT}
3640      *     translucency is not supported and the opacity is less than
3641      *     {@code 1.0f}
3642      *
3643      * @see Window#getOpacity
3644      * @see Window#setBackground(Color)
3645      * @see Window#setShape(Shape)
3646      * @see Frame#isUndecorated
3647      * @see Dialog#isUndecorated
3648      * @see GraphicsDevice.WindowTranslucency
3649      * @see GraphicsDevice#isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency)
3650      *
3651      * @since 1.7
3652      */
3653     @SuppressWarnings("deprecation")
setOpacity(float opacity)3654     public void setOpacity(float opacity) {
3655         synchronized (getTreeLock()) {
3656             if (opacity < 0.0f || opacity > 1.0f) {
3657                 throw new IllegalArgumentException(
3658                     "The value of opacity should be in the range [0.0f .. 1.0f].");
3659             }
3660             if (opacity < 1.0f) {
3661                 GraphicsConfiguration gc = getGraphicsConfiguration();
3662                 GraphicsDevice gd = gc.getDevice();
3663                 if (gc.getDevice().getFullScreenWindow() == this) {
3664                     throw new IllegalComponentStateException(
3665                         "Setting opacity for full-screen window is not supported.");
3666                 }
3667                 if (!gd.isWindowTranslucencySupported(
3668                     GraphicsDevice.WindowTranslucency.TRANSLUCENT))
3669                 {
3670                     throw new UnsupportedOperationException(
3671                         "TRANSLUCENT translucency is not supported.");
3672                 }
3673             }
3674             this.opacity = opacity;
3675             WindowPeer peer = (WindowPeer) this.peer;
3676             if (peer != null) {
3677                 peer.setOpacity(opacity);
3678             }
3679         }
3680     }
3681 
3682     /**
3683      * Returns the shape of the window.
3684      *
3685      * The value returned by this method may not be the same as
3686      * previously set with {@code setShape(shape)}, but it is guaranteed
3687      * to represent the same shape.
3688      *
3689      * @return the shape of the window or {@code null} if no
3690      *     shape is specified for the window
3691      *
3692      * @see Window#setShape(Shape)
3693      * @see GraphicsDevice.WindowTranslucency
3694      *
3695      * @since 1.7
3696      */
getShape()3697     public Shape getShape() {
3698         synchronized (getTreeLock()) {
3699             return shape == null ? null : new Path2D.Float(shape);
3700         }
3701     }
3702 
3703     /**
3704      * Sets the shape of the window.
3705      * <p>
3706      * Setting a shape cuts off some parts of the window. Only the parts that
3707      * belong to the given {@link Shape} remain visible and clickable. If
3708      * the shape argument is {@code null}, this method restores the default
3709      * shape, making the window rectangular on most platforms.
3710      * <p>
3711      * The following conditions must be met to set a non-null shape:
3712      * <ul>
3713      * <li>The {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSPARENT
3714      * PERPIXEL_TRANSPARENT} translucency must be supported by the
3715      * underlying system
3716      * <li>The window must be undecorated (see {@link Frame#setUndecorated}
3717      * and {@link Dialog#setUndecorated})
3718      * <li>The window must not be in full-screen mode (see {@link
3719      * GraphicsDevice#setFullScreenWindow(Window)})
3720      * </ul>
3721      * <p>
3722      * If the requested shape is not {@code null}, and any of the above
3723      * conditions are not met, the shape of this window will not change,
3724      * and either the {@code UnsupportedOperationException} or {@code
3725      * IllegalComponentStateException} will be thrown.
3726      * <p>
3727      * The translucency levels of individual pixels may also be effected by the
3728      * alpha component of their color (see {@link Window#setBackground(Color)}) and the
3729      * opacity value (see {@link #setOpacity(float)}). See {@link
3730      * GraphicsDevice.WindowTranslucency} for more details.
3731      *
3732      * @param shape the shape to set to the window
3733      *
3734      * @throws IllegalComponentStateException if the shape is not {@code
3735      *     null} and the window is decorated
3736      * @throws IllegalComponentStateException if the shape is not {@code
3737      *     null} and the window is in full-screen mode
3738      * @throws UnsupportedOperationException if the shape is not {@code
3739      *     null} and {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSPARENT
3740      *     PERPIXEL_TRANSPARENT} translucency is not supported
3741      *
3742      * @see Window#getShape()
3743      * @see Window#setBackground(Color)
3744      * @see Window#setOpacity(float)
3745      * @see Frame#isUndecorated
3746      * @see Dialog#isUndecorated
3747      * @see GraphicsDevice.WindowTranslucency
3748      * @see GraphicsDevice#isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency)
3749      *
3750      * @since 1.7
3751      */
setShape(Shape shape)3752     public void setShape(Shape shape) {
3753         synchronized (getTreeLock()) {
3754             if (shape != null) {
3755                 GraphicsConfiguration gc = getGraphicsConfiguration();
3756                 GraphicsDevice gd = gc.getDevice();
3757                 if (gc.getDevice().getFullScreenWindow() == this) {
3758                     throw new IllegalComponentStateException(
3759                         "Setting shape for full-screen window is not supported.");
3760                 }
3761                 if (!gd.isWindowTranslucencySupported(
3762                         GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSPARENT))
3763                 {
3764                     throw new UnsupportedOperationException(
3765                         "PERPIXEL_TRANSPARENT translucency is not supported.");
3766                 }
3767             }
3768             this.shape = (shape == null) ? null : new Path2D.Float(shape);
3769             WindowPeer peer = (WindowPeer) this.peer;
3770             if (peer != null) {
3771                 peer.applyShape(shape == null ? null : Region.getInstance(shape, null));
3772             }
3773         }
3774     }
3775 
3776     /**
3777      * Gets the background color of this window.
3778      * <p>
3779      * Note that the alpha component of the returned color indicates whether
3780      * the window is in the non-opaque (per-pixel translucent) mode.
3781      *
3782      * @return this component's background color
3783      *
3784      * @see Window#setBackground(Color)
3785      * @see Window#isOpaque
3786      * @see GraphicsDevice.WindowTranslucency
3787      */
3788     @Override
getBackground()3789     public Color getBackground() {
3790         return super.getBackground();
3791     }
3792 
3793     /**
3794      * Sets the background color of this window.
3795      * <p>
3796      * If the windowing system supports the {@link
3797      * GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT PERPIXEL_TRANSLUCENT}
3798      * translucency, the alpha component of the given background color
3799      * may effect the mode of operation for this window: it indicates whether
3800      * this window must be opaque (alpha equals {@code 1.0f}) or per-pixel translucent
3801      * (alpha is less than {@code 1.0f}). If the given background color is
3802      * {@code null}, the window is considered completely opaque.
3803      * <p>
3804      * All the following conditions must be met to enable the per-pixel
3805      * transparency mode for this window:
3806      * <ul>
3807      * <li>The {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
3808      * PERPIXEL_TRANSLUCENT} translucency must be supported by the graphics
3809      * device where this window is located
3810      * <li>The window must be undecorated (see {@link Frame#setUndecorated}
3811      * and {@link Dialog#setUndecorated})
3812      * <li>The window must not be in full-screen mode (see {@link
3813      * GraphicsDevice#setFullScreenWindow(Window)})
3814      * </ul>
3815      * <p>
3816      * If the alpha component of the requested background color is less than
3817      * {@code 1.0f}, and any of the above conditions are not met, the background
3818      * color of this window will not change, the alpha component of the given
3819      * background color will not affect the mode of operation for this window,
3820      * and either the {@code UnsupportedOperationException} or {@code
3821      * IllegalComponentStateException} will be thrown.
3822      * <p>
3823      * When the window is per-pixel translucent, the drawing sub-system
3824      * respects the alpha value of each individual pixel. If a pixel gets
3825      * painted with the alpha color component equal to zero, it becomes
3826      * visually transparent. If the alpha of the pixel is equal to 1.0f, the
3827      * pixel is fully opaque. Interim values of the alpha color component make
3828      * the pixel semi-transparent. In this mode, the background of the window
3829      * gets painted with the alpha value of the given background color. If the
3830      * alpha value of the argument of this method is equal to {@code 0}, the
3831      * background is not painted at all.
3832      * <p>
3833      * The actual level of translucency of a given pixel also depends on window
3834      * opacity (see {@link #setOpacity(float)}), as well as the current shape of
3835      * this window (see {@link #setShape(Shape)}).
3836      * <p>
3837      * Note that painting a pixel with the alpha value of {@code 0} may or may
3838      * not disable the mouse event handling on this pixel. This is a
3839      * platform-dependent behavior. To make sure the mouse events do not get
3840      * dispatched to a particular pixel, the pixel must be excluded from the
3841      * shape of the window.
3842      * <p>
3843      * Enabling the per-pixel translucency mode may change the graphics
3844      * configuration of this window due to the native platform requirements.
3845      *
3846      * @param bgColor the color to become this window's background color.
3847      *
3848      * @throws IllegalComponentStateException if the alpha value of the given
3849      *     background color is less than {@code 1.0f} and the window is decorated
3850      * @throws IllegalComponentStateException if the alpha value of the given
3851      *     background color is less than {@code 1.0f} and the window is in
3852      *     full-screen mode
3853      * @throws UnsupportedOperationException if the alpha value of the given
3854      *     background color is less than {@code 1.0f} and {@link
3855      *     GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT
3856      *     PERPIXEL_TRANSLUCENT} translucency is not supported
3857      *
3858      * @see Window#getBackground
3859      * @see Window#isOpaque
3860      * @see Window#setOpacity(float)
3861      * @see Window#setShape(Shape)
3862      * @see Frame#isUndecorated
3863      * @see Dialog#isUndecorated
3864      * @see GraphicsDevice.WindowTranslucency
3865      * @see GraphicsDevice#isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency)
3866      * @see GraphicsConfiguration#isTranslucencyCapable()
3867      */
3868     @Override
setBackground(Color bgColor)3869     public void setBackground(Color bgColor) {
3870         Color oldBg = getBackground();
3871         super.setBackground(bgColor);
3872         if (oldBg != null && oldBg.equals(bgColor)) {
3873             return;
3874         }
3875         int oldAlpha = oldBg != null ? oldBg.getAlpha() : 255;
3876         int alpha = bgColor != null ? bgColor.getAlpha() : 255;
3877         if ((oldAlpha == 255) && (alpha < 255)) { // non-opaque window
3878             GraphicsConfiguration gc = getGraphicsConfiguration();
3879             GraphicsDevice gd = gc.getDevice();
3880             if (gc.getDevice().getFullScreenWindow() == this) {
3881                 throw new IllegalComponentStateException(
3882                     "Making full-screen window non opaque is not supported.");
3883             }
3884             if (!gc.isTranslucencyCapable()) {
3885                 GraphicsConfiguration capableGC = gd.getTranslucencyCapableGC();
3886                 if (capableGC == null) {
3887                     throw new UnsupportedOperationException(
3888                         "PERPIXEL_TRANSLUCENT translucency is not supported");
3889                 }
3890                 setGraphicsConfiguration(capableGC);
3891             }
3892             setLayersOpaque(this, false);
3893         } else if ((oldAlpha < 255) && (alpha == 255)) {
3894             setLayersOpaque(this, true);
3895         }
3896         WindowPeer peer = (WindowPeer) this.peer;
3897         if (peer != null) {
3898             peer.setOpaque(alpha == 255);
3899         }
3900     }
3901 
3902     /**
3903      * Indicates if the window is currently opaque.
3904      * <p>
3905      * The method returns {@code false} if the background color of the window
3906      * is not {@code null} and the alpha component of the color is less than
3907      * {@code 1.0f}. The method returns {@code true} otherwise.
3908      *
3909      * @return {@code true} if the window is opaque, {@code false} otherwise
3910      *
3911      * @see Window#getBackground
3912      * @see Window#setBackground(Color)
3913      * @since 1.7
3914      */
3915     @Override
isOpaque()3916     public boolean isOpaque() {
3917         Color bg = getBackground();
3918         return bg != null ? bg.getAlpha() == 255 : true;
3919     }
3920 
updateWindow()3921     private void updateWindow() {
3922         synchronized (getTreeLock()) {
3923             WindowPeer peer = (WindowPeer) this.peer;
3924             if (peer != null) {
3925                 peer.updateWindow();
3926             }
3927         }
3928     }
3929 
3930     /**
3931      * {@inheritDoc}
3932      *
3933      * @since 1.7
3934      */
3935     @Override
paint(Graphics g)3936     public void paint(Graphics g) {
3937         if (!isOpaque()) {
3938             Graphics gg = g.create();
3939             try {
3940                 if (gg instanceof Graphics2D) {
3941                     gg.setColor(getBackground());
3942                     ((Graphics2D)gg).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC));
3943                     gg.fillRect(0, 0, getWidth(), getHeight());
3944                 }
3945             } finally {
3946                 gg.dispose();
3947             }
3948         }
3949         super.paint(g);
3950     }
3951 
setLayersOpaque(Component component, boolean isOpaque)3952     private static void setLayersOpaque(Component component, boolean isOpaque) {
3953         // Shouldn't use instanceof to avoid loading Swing classes
3954         //    if it's a pure AWT application.
3955         if (SunToolkit.isInstanceOf(component, "javax.swing.RootPaneContainer")) {
3956             javax.swing.RootPaneContainer rpc = (javax.swing.RootPaneContainer)component;
3957             javax.swing.JRootPane root = rpc.getRootPane();
3958             javax.swing.JLayeredPane lp = root.getLayeredPane();
3959             Container c = root.getContentPane();
3960             javax.swing.JComponent content =
3961                 (c instanceof javax.swing.JComponent) ? (javax.swing.JComponent)c : null;
3962             lp.setOpaque(isOpaque);
3963             root.setOpaque(isOpaque);
3964             if (content != null) {
3965                 content.setOpaque(isOpaque);
3966 
3967                 // Iterate down one level to see whether we have a JApplet
3968                 // (which is also a RootPaneContainer) which requires processing
3969                 int numChildren = content.getComponentCount();
3970                 if (numChildren > 0) {
3971                     Component child = content.getComponent(0);
3972                     // It's OK to use instanceof here because we've
3973                     // already loaded the RootPaneContainer class by now
3974                     if (child instanceof javax.swing.RootPaneContainer) {
3975                         setLayersOpaque(child, isOpaque);
3976                     }
3977                 }
3978             }
3979         }
3980     }
3981 
3982 
3983     // ************************** MIXING CODE *******************************
3984 
3985     // A window has an owner, but it does NOT have a container
3986     @Override
getContainer()3987     final Container getContainer() {
3988         return null;
3989     }
3990 
3991     /**
3992      * Applies the shape to the component
3993      * @param shape Shape to be applied to the component
3994      */
3995     @Override
applyCompoundShape(Region shape)3996     final void applyCompoundShape(Region shape) {
3997         // The shape calculated by mixing code is not intended to be applied
3998         // to windows or frames
3999     }
4000 
4001     @Override
applyCurrentShape()4002     final void applyCurrentShape() {
4003         // The shape calculated by mixing code is not intended to be applied
4004         // to windows or frames
4005     }
4006 
4007     @Override
mixOnReshaping()4008     final void mixOnReshaping() {
4009         // The shape calculated by mixing code is not intended to be applied
4010         // to windows or frames
4011     }
4012 
4013     @Override
getLocationOnWindow()4014     final Point getLocationOnWindow() {
4015         return new Point(0, 0);
4016     }
4017 
4018     // ****************** END OF MIXING CODE ********************************
4019 
4020     /**
4021      * Limit the given double value with the given range.
4022      */
limit(double value, double min, double max)4023     private static double limit(double value, double min, double max) {
4024         value = Math.max(value, min);
4025         value = Math.min(value, max);
4026         return value;
4027     }
4028 
4029     /**
4030      * Calculate the position of the security warning.
4031      *
4032      * This method gets the window location/size as reported by the native
4033      * system since the locally cached values may represent outdated data.
4034      *
4035      * The method is used from the native code, or via AWTAccessor.
4036      *
4037      * NOTE: this method is invoked on the toolkit thread, and therefore is not
4038      * supposed to become public/user-overridable.
4039      */
calculateSecurityWarningPosition(double x, double y, double w, double h)4040     private Point2D calculateSecurityWarningPosition(double x, double y,
4041             double w, double h)
4042     {
4043          // The desired location for the security warning
4044         double wx = x + w * RIGHT_ALIGNMENT + 2.0;
4045         double wy = y + h * TOP_ALIGNMENT + 0.0;
4046 
4047         // First, make sure the warning is not too far from the window bounds
4048         wx = Window.limit(wx,
4049                 x - securityWarningWidth - 2,
4050                 x + w + 2);
4051         wy = Window.limit(wy,
4052                 y - securityWarningHeight - 2,
4053                 y + h + 2);
4054 
4055         // Now make sure the warning window is visible on the screen
4056         GraphicsConfiguration graphicsConfig =
4057             getGraphicsConfiguration_NoClientCode();
4058         Rectangle screenBounds = graphicsConfig.getBounds();
4059         Insets screenInsets =
4060             Toolkit.getDefaultToolkit().getScreenInsets(graphicsConfig);
4061 
4062         wx = Window.limit(wx,
4063                 screenBounds.x + screenInsets.left,
4064                 screenBounds.x + screenBounds.width - screenInsets.right
4065                 - securityWarningWidth);
4066         wy = Window.limit(wy,
4067                 screenBounds.y + screenInsets.top,
4068                 screenBounds.y + screenBounds.height - screenInsets.bottom
4069                 - securityWarningHeight);
4070 
4071         return new Point2D.Double(wx, wy);
4072     }
4073 
4074     static {
AWTAccessor.setWindowAccessor(new AWTAccessor.WindowAccessor() { public void updateWindow(Window window) { window.updateWindow(); } public void setSecurityWarningSize(Window window, int width, int height) { window.securityWarningWidth = width; window.securityWarningHeight = height; } public Point2D calculateSecurityWarningPosition(Window window, double x, double y, double w, double h) { return window.calculateSecurityWarningPosition(x, y, w, h); } public void setLWRequestStatus(Window changed, boolean status) { changed.syncLWRequests = status; } public boolean isAutoRequestFocus(Window w) { return w.autoRequestFocus; } public boolean isTrayIconWindow(Window w) { return w.isTrayIconWindow; } public void setTrayIconWindow(Window w, boolean isTrayIconWindow) { w.isTrayIconWindow = isTrayIconWindow; } public Window[] getOwnedWindows(Window w) { return w.getOwnedWindows_NoClientCode(); } })4075         AWTAccessor.setWindowAccessor(new AWTAccessor.WindowAccessor() {
4076             public void updateWindow(Window window) {
4077                 window.updateWindow();
4078             }
4079 
4080             public void setSecurityWarningSize(Window window, int width, int height)
4081             {
4082                 window.securityWarningWidth = width;
4083                 window.securityWarningHeight = height;
4084             }
4085 
4086             public Point2D calculateSecurityWarningPosition(Window window,
4087                     double x, double y, double w, double h)
4088             {
4089                 return window.calculateSecurityWarningPosition(x, y, w, h);
4090             }
4091 
4092             public void setLWRequestStatus(Window changed, boolean status) {
4093                 changed.syncLWRequests = status;
4094             }
4095 
4096             public boolean isAutoRequestFocus(Window w) {
4097                 return w.autoRequestFocus;
4098             }
4099 
4100             public boolean isTrayIconWindow(Window w) {
4101                 return w.isTrayIconWindow;
4102             }
4103 
4104             public void setTrayIconWindow(Window w, boolean isTrayIconWindow) {
4105                 w.isTrayIconWindow = isTrayIconWindow;
4106             }
4107 
4108             public Window[] getOwnedWindows(Window w) {
4109                 return w.getOwnedWindows_NoClientCode();
4110             }
4111         }); // WindowAccessor
4112     } // static
4113 
4114     // a window doesn't need to be updated in the Z-order.
4115     @Override
updateZOrder()4116     void updateZOrder() {}
4117 
4118 } // class Window
4119 
4120 
4121 /**
4122  * This class is no longer used, but is maintained for Serialization
4123  * backward-compatibility.
4124  */
4125 class FocusManager implements java.io.Serializable {
4126     Container focusRoot;
4127     Component focusOwner;
4128 
4129     /*
4130      * JDK 1.1 serialVersionUID
4131      */
4132     static final long serialVersionUID = 2491878825643557906L;
4133 }
4134