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