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 returns <code>true</code>, then
2354 * <code>isFocusableWindow</code> may return <code>true</code> or
2355 * <code>false</code> depending upon the other requirements which must be
2356 * met in order for a Window to be focusable.
2357 * <p>
2358 * By default, all Windows have a focusable Window state of
2359 * <code>true</code>.
2360 *
2361 * @return whether this Window can be the focused Window
2362 * @see #isFocusableWindow
2363 * @see #setFocusableWindowState
2364 * @see #isShowing
2365 * @see Component#setFocusable
2366 * @since 1.4
2367 */
2368 public boolean getFocusableWindowState() {
2369 return focusableWindowState;
2370 }
2371
2372 /**
2373 * Sets whether this Window can become the focused Window if it meets
2374 * the other requirements outlined in <code>isFocusableWindow</code>. If
2375 * this Window's focusable Window state is set to <code>false</code>, then
2376 * <code>isFocusableWindow</code> will return <code>false</code>. If this
2377 * Window's focusable Window state is set to <code>true</code>, then
2378 * <code>isFocusableWindow</code> may return <code>true</code> or
2379 * <code>false</code> depending upon the other requirements which must be
2380 * met in order for a Window to be focusable.
2381 * <p>
2382 * Setting a Window's focusability state to <code>false</code> is the
2383 * standard mechanism for an application to identify to the AWT a Window
2384 * which will be used as a floating palette or toolbar, and thus should be
2385 * a non-focusable Window.
2386 *
2387 * Setting the focusability state on a visible <code>Window</code>
2388 * can have a delayed effect on some platforms — the actual
2389 * change may happen only when the <code>Window</code> becomes
2390 * hidden and then visible again. To ensure consistent behavior
2391 * across platforms, set the <code>Window</code>'s focusable state
2392 * when the <code>Window</code> is invisible and then show it.
2393 *
2394 * @param focusableWindowState whether this Window can be the focused
2395 * Window
2396 * @see #isFocusableWindow
2397 * @see #getFocusableWindowState
2398 * @see #isShowing
2399 * @see Component#setFocusable
2400 * @since 1.4
2401 */
2402 public void setFocusableWindowState(boolean focusableWindowState) {
2403 boolean oldFocusableWindowState;
2404 synchronized (this) {
2405 oldFocusableWindowState = this.focusableWindowState;
2406 this.focusableWindowState = focusableWindowState;
2407 }
2408 WindowPeer peer = (WindowPeer)this.peer;
2409 if (peer != null) {
2410 peer.updateFocusableWindowState();
2411 }
2412 firePropertyChange("focusableWindowState", oldFocusableWindowState,
2413 focusableWindowState);
2414 if (oldFocusableWindowState && !focusableWindowState && isFocused()) {
2415 for (Window owner = getOwner();
2416 owner != null;
2417 owner = owner.getOwner())
2418 {
2419 Component toFocus =
2420 KeyboardFocusManager.getMostRecentFocusOwner(owner);
2421 if (toFocus != null && toFocus.requestFocus(false, CausedFocusEvent.Cause.ACTIVATION)) {
2422 return;
2423 }
2424 }
2425 KeyboardFocusManager.getCurrentKeyboardFocusManager().
2426 clearGlobalFocusOwner();
2427 }
2428 }
2429
2430 /**
2431 * Sets whether this window should receive focus on
2432 * subsequently being shown (with a call to {@link #setVisible setVisible(true)}),
2433 * or being moved to the front (with a call to {@link #toFront}).
2434 * <p>
2435 * Note that {@link #setVisible setVisible(true)} may be called indirectly
2436 * (e.g. when showing an owner of the window makes the window to be shown).
2437 * {@link #toFront} may also be called indirectly (e.g. when
2438 * {@link #setVisible setVisible(true)} is called on already visible window).
2439 * In all such cases this property takes effect as well.
2440 * <p>
2441 * The value of the property is not inherited by owned windows.
2442 *
2443 * @param autoRequestFocus whether this window should be focused on
2444 * subsequently being shown or being moved to the front
2445 * @see #isAutoRequestFocus
2446 * @see #isFocusableWindow
2447 * @see #setVisible
2448 * @see #toFront
2449 * @since 1.7
2450 */
2451 public void setAutoRequestFocus(boolean autoRequestFocus) {
2452 this.autoRequestFocus = autoRequestFocus;
2453 }
2454
2455 /**
2456 * Returns whether this window should receive focus on subsequently being shown
2457 * (with a call to {@link #setVisible setVisible(true)}), or being moved to the front
2458 * (with a call to {@link #toFront}).
2459 * <p>
2460 * By default, the window has {@code autoRequestFocus} value of {@code true}.
2461 *
2462 * @return {@code autoRequestFocus} value
2463 * @see #setAutoRequestFocus
2464 * @since 1.7
2465 */
2466 public boolean isAutoRequestFocus() {
2467 return autoRequestFocus;
2468 }
2469
2470 /**
2471 * Adds a PropertyChangeListener to the listener list. The listener is
2472 * registered for all bound properties of this class, including the
2473 * following:
2474 * <ul>
2475 * <li>this Window's font ("font")</li>
2476 * <li>this Window's background color ("background")</li>
2477 * <li>this Window's foreground color ("foreground")</li>
2478 * <li>this Window's focusability ("focusable")</li>
2479 * <li>this Window's focus traversal keys enabled state
2480 * ("focusTraversalKeysEnabled")</li>
2481 * <li>this Window's Set of FORWARD_TRAVERSAL_KEYS
2482 * ("forwardFocusTraversalKeys")</li>
2483 * <li>this Window's Set of BACKWARD_TRAVERSAL_KEYS
2484 * ("backwardFocusTraversalKeys")</li>
2485 * <li>this Window's Set of UP_CYCLE_TRAVERSAL_KEYS
2486 * ("upCycleFocusTraversalKeys")</li>
2487 * <li>this Window's Set of DOWN_CYCLE_TRAVERSAL_KEYS
2488 * ("downCycleFocusTraversalKeys")</li>
2489 * <li>this Window's focus traversal policy ("focusTraversalPolicy")
2490 * </li>
2491 * <li>this Window's focusable Window state ("focusableWindowState")
2492 * </li>
2493 * <li>this Window's always-on-top state("alwaysOnTop")</li>
2494 * </ul>
2495 * Note that if this Window is inheriting a bound property, then no
2496 * event will be fired in response to a change in the inherited property.
2497 * <p>
2498 * If listener is null, no exception is thrown and no action is performed.
2499 *
2500 * @param listener the PropertyChangeListener to be added
2501 *
2502 * @see Component#removePropertyChangeListener
2503 * @see #addPropertyChangeListener(java.lang.String,java.beans.PropertyChangeListener)
2504 */
2505 public void addPropertyChangeListener(PropertyChangeListener listener) {
2506 super.addPropertyChangeListener(listener);
2507 }
2508
2509 /**
2510 * Adds a PropertyChangeListener to the listener list for a specific
2511 * property. The specified property may be user-defined, or one of the
2512 * following:
2513 * <ul>
2514 * <li>this Window's font ("font")</li>
2515 * <li>this Window's background color ("background")</li>
2516 * <li>this Window's foreground color ("foreground")</li>
2517 * <li>this Window's focusability ("focusable")</li>
2518 * <li>this Window's focus traversal keys enabled state
2519 * ("focusTraversalKeysEnabled")</li>
2520 * <li>this Window's Set of FORWARD_TRAVERSAL_KEYS
2521 * ("forwardFocusTraversalKeys")</li>
2522 * <li>this Window's Set of BACKWARD_TRAVERSAL_KEYS
2523 * ("backwardFocusTraversalKeys")</li>
2524 * <li>this Window's Set of UP_CYCLE_TRAVERSAL_KEYS
2525 * ("upCycleFocusTraversalKeys")</li>
2526 * <li>this Window's Set of DOWN_CYCLE_TRAVERSAL_KEYS
2527 * ("downCycleFocusTraversalKeys")</li>
2528 * <li>this Window's focus traversal policy ("focusTraversalPolicy")
2529 * </li>
2530 * <li>this Window's focusable Window state ("focusableWindowState")
2531 * </li>
2532 * <li>this Window's always-on-top state("alwaysOnTop")</li>
2533 * </ul>
2534 * Note that if this Window is inheriting a bound property, then no
2535 * event will be fired in response to a change in the inherited property.
2536 * <p>
2537 * If listener is null, no exception is thrown and no action is performed.
2538 *
2539 * @param propertyName one of the property names listed above
2540 * @param listener the PropertyChangeListener to be added
2541 *
2542 * @see #addPropertyChangeListener(java.beans.PropertyChangeListener)
2543 * @see Component#removePropertyChangeListener
2544 */
2545 public void addPropertyChangeListener(String propertyName,
2546 PropertyChangeListener listener) {
2547 super.addPropertyChangeListener(propertyName, listener);
2548 }
2549
2550 /**
2551 * Dispatches an event to this window or one of its sub components.
2552 * @param e the event
2553 */
2554 void dispatchEventImpl(AWTEvent e) {
2555 if (e.getID() == ComponentEvent.COMPONENT_RESIZED) {
2556 invalidate();
2557 validate();
2558 }
2559 super.dispatchEventImpl(e);
2560 }
2561
2562 /**
2563 * @deprecated As of JDK version 1.1
2564 * replaced by <code>dispatchEvent(AWTEvent)</code>.
2565 */
2566 @Deprecated
2567 public boolean postEvent(Event e) {
2568 if (handleEvent(e)) {
2569 e.consume();
2570 return true;
2571 }
2572 return false;
2573 }
2574
2575 /**
2576 * Checks if this Window is showing on screen.
2577 * @see Component#setVisible
2578 */
2579 public boolean isShowing() {
2580 return visible;
2581 }
2582
2583 /**
2584 * @deprecated As of J2SE 1.4, replaced by
2585 * {@link Component#applyComponentOrientation Component.applyComponentOrientation}.
2586 */
2587 @Deprecated
2588 public void applyResourceBundle(ResourceBundle rb) {
2589 applyComponentOrientation(ComponentOrientation.getOrientation(rb));
2590 }
2591
2592 /**
2593 * @deprecated As of J2SE 1.4, replaced by
2594 * {@link Component#applyComponentOrientation Component.applyComponentOrientation}.
2595 */
2596 @Deprecated
2597 public void applyResourceBundle(String rbName) {
2598 applyResourceBundle(ResourceBundle.getBundle(rbName));
2599 }
2600
2601 /*
2602 * Support for tracking all windows owned by this window
2603 */
2604 void addOwnedWindow(WeakReference weakWindow) {
2605 if (weakWindow != null) {
2606 synchronized(ownedWindowList) {
2607 // this if statement should really be an assert, but we don't
2608 // have asserts...
2609 if (!ownedWindowList.contains(weakWindow)) {
2610 ownedWindowList.addElement(weakWindow);
2611 }
2612 }
2613 }
2614 }
2615
2616 void removeOwnedWindow(WeakReference weakWindow) {
2617 if (weakWindow != null) {
2618 // synchronized block not required since removeElement is
2619 // already synchronized
2620 ownedWindowList.removeElement(weakWindow);
2621 }
2622 }
2623
2624 void connectOwnedWindow(Window child) {
2625 child.parent = this;
2626 addOwnedWindow(child.weakThis);
2627 }
2628
2629 private void addToWindowList() {
2630 synchronized (Window.class) {
2631 Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)appContext.get(Window.class);
2632 if (windowList == null) {
2633 windowList = new Vector<WeakReference<Window>>();
2634 appContext.put(Window.class, windowList);
2635 }
2636 windowList.add(weakThis);
2637 }
2638 }
2639
2640 private static void removeFromWindowList(AppContext context, WeakReference weakThis) {
2641 synchronized (Window.class) {
2642 Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)context.get(Window.class);
2643 if (windowList != null) {
2644 windowList.remove(weakThis);
2645 }
2646 }
2647 }
2648
2649 private void removeFromWindowList() {
2650 removeFromWindowList(appContext, weakThis);
2651 }
2652
2653 /**
2654 * The window serialized data version.
2655 *
2656 * @serial
2657 */
2658 private int windowSerializedDataVersion = 2;
2659
2660 /**
2661 * Writes default serializable fields to stream. Writes
2662 * a list of serializable <code>WindowListener</code>s and
2663 * <code>WindowFocusListener</code>s as optional data.
2664 * Writes a list of child windows as optional data.
2665 * Writes a list of icon images as optional data
2666 *
2667 * @param s the <code>ObjectOutputStream</code> to write
2668 * @serialData <code>null</code> terminated sequence of
2669 * 0 or more pairs; the pair consists of a <code>String</code>
2670 * and and <code>Object</code>; the <code>String</code>
2671 * indicates the type of object and is one of the following:
2672 * <code>windowListenerK</code> indicating a
2673 * <code>WindowListener</code> object;
2674 * <code>windowFocusWindowK</code> indicating a
2675 * <code>WindowFocusListener</code> object;
2676 * <code>ownedWindowK</code> indicating a child
2677 * <code>Window</code> object
2678 *
2679 * @see AWTEventMulticaster#save(java.io.ObjectOutputStream, java.lang.String, java.util.EventListener)
2680 * @see Component#windowListenerK
2681 * @see Component#windowFocusListenerK
2682 * @see Component#ownedWindowK
2683 * @see #readObject(ObjectInputStream)
2684 */
2685 private void writeObject(ObjectOutputStream s) throws IOException {
2686 synchronized (this) {
2687 // Update old focusMgr fields so that our object stream can be read
2688 // by previous releases
2689 focusMgr = new FocusManager();
2690 focusMgr.focusRoot = this;
2691 focusMgr.focusOwner = getMostRecentFocusOwner();
2692
2693 s.defaultWriteObject();
2694
2695 // Clear fields so that we don't keep extra references around
2696 focusMgr = null;
2697
2698 AWTEventMulticaster.save(s, windowListenerK, windowListener);
2699 AWTEventMulticaster.save(s, windowFocusListenerK, windowFocusListener);
2700 AWTEventMulticaster.save(s, windowStateListenerK, windowStateListener);
2701 }
2702
2703 s.writeObject(null);
2704
2705 synchronized (ownedWindowList) {
2706 for (int i = 0; i < ownedWindowList.size(); i++) {
2707 Window child = ownedWindowList.elementAt(i).get();
2708 if (child != null) {
2709 s.writeObject(ownedWindowK);
2710 s.writeObject(child);
2711 }
2712 }
2713 }
2714 s.writeObject(null);
2715
2716 //write icon array
2717 if (icons != null) {
2718 for (Image i : icons) {
2719 if (i instanceof Serializable) {
2720 s.writeObject(i);
2721 }
2722 }
2723 }
2724 s.writeObject(null);
2725 }
2726
2727 //
2728 // Part of deserialization procedure to be called before
2729 // user's code.
2730 //
2731 private void initDeserializedWindow() {
2732 setWarningString();
2733 inputContextLock = new Object();
2734
2735 // Deserialized Windows are not yet visible.
2736 visible = false;
2737
2738 weakThis = new WeakReference(this);
2739
2740 anchor = new Object();
2741 sun.java2d.Disposer.addRecord(anchor, new WindowDisposerRecord(appContext, this));
2742
2743 addToWindowList();
2744
2745 }
2746
2747 private void deserializeResources(ObjectInputStream s)
2748 throws ClassNotFoundException, IOException, HeadlessException {
2749 ownedWindowList = new Vector();
2750
2751 if (windowSerializedDataVersion < 2) {
2752 // Translate old-style focus tracking to new model. For 1.4 and
2753 // later releases, we'll rely on the Window's initial focusable
2754 // Component.
2755 if (focusMgr != null) {
2756 if (focusMgr.focusOwner != null) {
2757 KeyboardFocusManager.
2758 setMostRecentFocusOwner(this, focusMgr.focusOwner);
2759 }
2760 }
2761
2762 // This field is non-transient and relies on default serialization.
2763 // However, the default value is insufficient, so we need to set
2764 // it explicitly for object data streams prior to 1.4.
2765 focusableWindowState = true;
2766
2767
2768 }
2769
2770 Object keyOrNull;
2771 while(null != (keyOrNull = s.readObject())) {
2772 String key = ((String)keyOrNull).intern();
2773
2774 if (windowListenerK == key) {
2775 addWindowListener((WindowListener)(s.readObject()));
2776 } else if (windowFocusListenerK == key) {
2777 addWindowFocusListener((WindowFocusListener)(s.readObject()));
2778 } else if (windowStateListenerK == key) {
2779 addWindowStateListener((WindowStateListener)(s.readObject()));
2780 } else // skip value for unrecognized key
2781 s.readObject();
2782 }
2783
2784 try {
2785 while (null != (keyOrNull = s.readObject())) {
2786 String key = ((String)keyOrNull).intern();
2787
2788 if (ownedWindowK == key)
2789 connectOwnedWindow((Window) s.readObject());
2790
2791 else // skip value for unrecognized key
2792 s.readObject();
2793 }
2794
2795 //read icons
2796 Object obj = s.readObject(); //Throws OptionalDataException
2797 //for pre1.6 objects.
2798 icons = new ArrayList<Image>(); //Frame.readObject() assumes
2799 //pre1.6 version if icons is null.
2800 while (obj != null) {
2801 if (obj instanceof Image) {
2802 icons.add((Image)obj);
2803 }
2804 obj = s.readObject();
2805 }
2806 }
2807 catch (OptionalDataException e) {
2808 // 1.1 serialized form
2809 // ownedWindowList will be updated by Frame.readObject
2810 }
2811
2812 }
2813
2814 /**
2815 * Reads the <code>ObjectInputStream</code> and an optional
2816 * list of listeners to receive various events fired by
2817 * the component; also reads a list of
2818 * (possibly <code>null</code>) child windows.
2819 * Unrecognized keys or values will be ignored.
2820 *
2821 * @param s the <code>ObjectInputStream</code> to read
2822 * @exception HeadlessException if
2823 * <code>GraphicsEnvironment.isHeadless</code> returns
2824 * <code>true</code>
2825 * @see java.awt.GraphicsEnvironment#isHeadless
2826 * @see #writeObject
2827 */
2828 private void readObject(ObjectInputStream s)
2829 throws ClassNotFoundException, IOException, HeadlessException
2830 {
2831 GraphicsEnvironment.checkHeadless();
2832 initDeserializedWindow();
2833 ObjectInputStream.GetField f = s.readFields();
2834
2835 syncLWRequests = f.get("syncLWRequests", systemSyncLWRequests);
2836 state = f.get("state", 0);
2837 focusableWindowState = f.get("focusableWindowState", true);
2838 windowSerializedDataVersion = f.get("windowSerializedDataVersion", 1);
2839 locationByPlatform = f.get("locationByPlatform", locationByPlatformProp);
2840 // Note: 1.4 (or later) doesn't use focusMgr
2841 focusMgr = (FocusManager)f.get("focusMgr", null);
2842 Dialog.ModalExclusionType et = (Dialog.ModalExclusionType)
2843 f.get("modalExclusionType", Dialog.ModalExclusionType.NO_EXCLUDE);
2844 setModalExclusionType(et); // since 6.0
2845 boolean aot = f.get("alwaysOnTop", false);
2846 if(aot) {
2847 setAlwaysOnTop(aot); // since 1.5; subject to permission check
2848 }
2849
2850 deserializeResources(s);
2851 }
2852
2853 /*
2854 * --- Accessibility Support ---
2855 *
2856 */
2857
2858 /**
2859 * Gets the AccessibleContext associated with this Window.
2860 * For windows, the AccessibleContext takes the form of an
2861 * AccessibleAWTWindow.
2862 * A new AccessibleAWTWindow instance is created if necessary.
2863 *
2864 * @return an AccessibleAWTWindow that serves as the
2865 * AccessibleContext of this Window
2866 * @since 1.3
2867 */
2868 public AccessibleContext getAccessibleContext() {
2869 if (accessibleContext == null) {
2870 accessibleContext = new AccessibleAWTWindow();
2871 }
2872 return accessibleContext;
2873 }
2874
2875 /**
2876 * This class implements accessibility support for the
2877 * <code>Window</code> class. It provides an implementation of the
2878 * Java Accessibility API appropriate to window user-interface elements.
2879 * @since 1.3
2880 */
2881 protected class AccessibleAWTWindow extends AccessibleAWTContainer
2882 {
2883 /*
2884 * JDK 1.3 serialVersionUID
2885 */
2886 private static final long serialVersionUID = 4215068635060671780L;
2887
2888 /**
2889 * Get the role of this object.
2890 *
2891 * @return an instance of AccessibleRole describing the role of the
2892 * object
2893 * @see javax.accessibility.AccessibleRole
2894 */
2895 public AccessibleRole getAccessibleRole() {
2896 return AccessibleRole.WINDOW;
2897 }
2898
2899 /**
2900 * Get the state of this object.
2901 *
2902 * @return an instance of AccessibleStateSet containing the current
2903 * state set of the object
2904 * @see javax.accessibility.AccessibleState
2905 */
2906 public AccessibleStateSet getAccessibleStateSet() {
2907 AccessibleStateSet states = super.getAccessibleStateSet();
2908 if (getFocusOwner() != null) {
2909 states.add(AccessibleState.ACTIVE);
2910 }
2911 return states;
2912 }
2913
2914 } // inner class AccessibleAWTWindow
2915
2916 /**
2917 * This method returns the GraphicsConfiguration used by this Window.
2918 * @since 1.3
2919 */
2920 public GraphicsConfiguration getGraphicsConfiguration() {
2921 //NOTE: for multiscreen, this will need to take into account
2922 //which screen the window is on/mostly on instead of returning the
2923 //default or constructor argument config.
2924 synchronized(getTreeLock()) {
2925 if (graphicsConfig == null && !GraphicsEnvironment.isHeadless()) {
2926 graphicsConfig =
2927 GraphicsEnvironment. getLocalGraphicsEnvironment().
2928 getDefaultScreenDevice().
2929 getDefaultConfiguration();
2930 }
2931 return graphicsConfig;
2932 }
2933 }
2934
2935 /**
2936 * Reset this Window's GraphicsConfiguration to match its peer.
2937 */
2938 void resetGC() {
2939 if (!GraphicsEnvironment.isHeadless()) {
2940 // use the peer's GC
2941 setGCFromPeer();
2942 // if it's still null, use the default
2943 if (graphicsConfig == null) {
2944 graphicsConfig = GraphicsEnvironment.
2945 getLocalGraphicsEnvironment().
2946 getDefaultScreenDevice().
2947 getDefaultConfiguration();
2948 }
2949 if (log.isLoggable(Level.FINER)) {
2950 log.finer("+ Window.resetGC(): new GC is \n+ " + graphicsConfig + "\n+ this is " + this);
2951 }
2952 }
2953 }
2954
2955 /**
2956 * Sets the location of the window relative to the specified
2957 * component according to the following scenarios.
2958 * <p>
2959 * The target screen mentioned below is a screen to which
2960 * the window should be placed after the setLocationRelativeTo
2961 * method is called.
2962 * <ul>
2963 * <li>If the component is {@code null}, or the {@code
2964 * GraphicsConfiguration} associated with this component is
2965 * {@code null}, the window is placed in the center of the
2966 * screen. The center point can be obtained with the {@link
2967 * GraphicsEnvironment#getCenterPoint
2968 * GraphicsEnvironment.getCenterPoint} method.
2969 * <li>If the component is not {@code null}, but it is not
2970 * currently showing, the window is placed in the center of
2971 * the target screen defined by the {@code
2972 * GraphicsConfiguration} associated with this component.
2973 * <li>If the component is not {@code null} and is shown on
2974 * the screen, then the window is located in such a way that
2975 * the center of the window coincides with the center of the
2976 * component.
2977 * </ul>
2978 * <p>
2979 * If the screens configuration does not allow the window to
2980 * be moved from one screen to another, then the window is
2981 * only placed at the location determined according to the
2982 * above conditions and its {@code GraphicsConfiguration} is
2983 * not changed.
2984 * <p>
2985 * <b>Note</b>: If the lower edge of the window is out of the screen,
2986 * then the window is placed to the side of the <code>Component</code>
2987 * that is closest to the center of the screen. So if the
2988 * component is on the right part of the screen, the window
2989 * is placed to its left, and vice versa.
2990 * <p>
2991 * If after the window location has been calculated, the upper,
2992 * left, or right edge of the window is out of the screen,
2993 * then the window is located in such a way that the upper,
2994 * left, or right edge of the window coincides with the
2995 * corresponding edge of the screen. If both left and right
2996 * edges of the window are out of the screen, the window is
2997 * placed at the left side of the screen. The similar placement
2998 * will occur if both top and bottom edges are out of the screen.
2999 * In that case, the window is placed at the top side of the screen.
3000 *
3001 * @param c the component in relation to which the window's location
3002 * is determined
3003 * @see java.awt.GraphicsEnvironment#getCenterPoint
3004 * @since 1.4
3005 */
3006 public void setLocationRelativeTo(Component c) {
3007 // target location
3008 int dx = 0, dy = 0;
3009 // target GC
3010 GraphicsConfiguration gc = this.graphicsConfig;
3011 Rectangle gcBounds = gc.getBounds();
3012
3013 Dimension windowSize = getSize();
3014
3015 // search a top-level of c
3016 Window componentWindow = Component.getContainingWindow(c);
3017 if ((c == null) || (componentWindow == null)) {
3018 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
3019 gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
3020 gcBounds = gc.getBounds();
3021 Point centerPoint = ge.getCenterPoint();
3022 dx = centerPoint.x - windowSize.width / 2;
3023 dy = centerPoint.y - windowSize.height / 2;
3024 } else if (!c.isShowing()) {
3025 gc = componentWindow.getGraphicsConfiguration();
3026 gcBounds = gc.getBounds();
3027 dx = gcBounds.x + (gcBounds.width - windowSize.width) / 2;
3028 dy = gcBounds.y + (gcBounds.height - windowSize.height) / 2;
3029 } else {
3030 gc = componentWindow.getGraphicsConfiguration();
3031 gcBounds = gc.getBounds();
3032 Dimension compSize = c.getSize();
3033 Point compLocation = c.getLocationOnScreen();
3034 dx = compLocation.x + ((compSize.width - windowSize.width) / 2);
3035 dy = compLocation.y + ((compSize.height - windowSize.height) / 2);
3036
3037 // Adjust for bottom edge being offscreen
3038 if (dy + windowSize.height > gcBounds.y + gcBounds.height) {
3039 dy = gcBounds.y + gcBounds.height - windowSize.height;
3040 if (compLocation.x - gcBounds.x + compSize.width / 2 < gcBounds.width / 2) {
3041 dx = compLocation.x + compSize.width;
3042 } else {
3043 dx = compLocation.x - windowSize.width;
3044 }
3045 }
3046 }
3047
3048 // Avoid being placed off the edge of the screen:
3049 // bottom
3050 if (dy + windowSize.height > gcBounds.y + gcBounds.height) {
3051 dy = gcBounds.y + gcBounds.height - windowSize.height;
3052 }
3053 // top
3054 if (dy < gcBounds.y) {
3055 dy = gcBounds.y;
3056 }
3057 // right
3058 if (dx + windowSize.width > gcBounds.x + gcBounds.width) {
3059 dx = gcBounds.x + gcBounds.width - windowSize.width;
3060 }
3061 // left
3062 if (dx < gcBounds.x) {
3063 dx = gcBounds.x;
3064 }
3065
3066 setLocation(dx, dy);
3067 }
3068
3069 /**
3070 * Overridden from Component. Top-level Windows should not propagate a
3071 * MouseWheelEvent beyond themselves into their owning Windows.
3072 */
3073 void deliverMouseWheelToAncestor(MouseWheelEvent e) {}
3074
3075 /**
3076 * Overridden from Component. Top-level Windows don't dispatch to ancestors
3077 */
3078 boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {return false;}
3079
3080 /**
3081 * Creates a new strategy for multi-buffering on this component.
3082 * Multi-buffering is useful for rendering performance. This method
3083 * attempts to create the best strategy available with the number of
3084 * buffers supplied. It will always create a <code>BufferStrategy</code>
3085 * with that number of buffers.
3086 * A page-flipping strategy is attempted first, then a blitting strategy
3087 * using accelerated buffers. Finally, an unaccelerated blitting
3088 * strategy is used.
3089 * <p>
3090 * Each time this method is called,
3091 * the existing buffer strategy for this component is discarded.
3092 * @param numBuffers number of buffers to create
3093 * @exception IllegalArgumentException if numBuffers is less than 1.
3094 * @exception IllegalStateException if the component is not displayable
3095 * @see #isDisplayable
3096 * @see #getBufferStrategy
3097 * @since 1.4
3098 */
3099 public void createBufferStrategy(int numBuffers) {
3100 super.createBufferStrategy(numBuffers);
3101 }
3102
3103 /**
3104 * Creates a new strategy for multi-buffering on this component with the
3105 * required buffer capabilities. This is useful, for example, if only
3106 * accelerated memory or page flipping is desired (as specified by the
3107 * buffer capabilities).
3108 * <p>
3109 * Each time this method
3110 * is called, the existing buffer strategy for this component is discarded.
3111 * @param numBuffers number of buffers to create, including the front buffer
3112 * @param caps the required capabilities for creating the buffer strategy;
3113 * cannot be <code>null</code>
3114 * @exception AWTException if the capabilities supplied could not be
3115 * supported or met; this may happen, for example, if there is not enough
3116 * accelerated memory currently available, or if page flipping is specified
3117 * but not possible.
3118 * @exception IllegalArgumentException if numBuffers is less than 1, or if
3119 * caps is <code>null</code>
3120 * @see #getBufferStrategy
3121 * @since 1.4
3122 */
3123 public void createBufferStrategy(int numBuffers,
3124 BufferCapabilities caps) throws AWTException {
3125 super.createBufferStrategy(numBuffers, caps);
3126 }
3127
3128 /**
3129 * Returns the <code>BufferStrategy</code> used by this component. This
3130 * method will return null if a <code>BufferStrategy</code> has not yet
3131 * been created or has been disposed.
3132 *
3133 * @return the buffer strategy used by this component
3134 * @see #createBufferStrategy
3135 * @since 1.4
3136 */
3137 public BufferStrategy getBufferStrategy() {
3138 return super.getBufferStrategy();
3139 }
3140
3141 Component getTemporaryLostComponent() {
3142 return temporaryLostComponent;
3143 }
3144 Component setTemporaryLostComponent(Component component) {
3145 Component previousComp = temporaryLostComponent;
3146 // Check that "component" is an acceptable focus owner and don't store it otherwise
3147 // - or later we will have problems with opposite while handling WINDOW_GAINED_FOCUS
3148 if (component == null
3149 || (component.isDisplayable() && component.isVisible() && component.isEnabled() && component.isFocusable()))
3150 {
3151 temporaryLostComponent = component;
3152 } else {
3153 temporaryLostComponent = null;
3154 }
3155 return previousComp;
3156 }
3157
3158 /**
3159 * Checks whether this window can contain focus owner.
3160 * Verifies that it is focusable and as container it can container focus owner.
3161 * @since 1.5
3162 */
3163 boolean canContainFocusOwner(Component focusOwnerCandidate) {
3164 return super.canContainFocusOwner(focusOwnerCandidate) && isFocusableWindow();
3165 }
3166
3167 private boolean locationByPlatform = locationByPlatformProp;
3168
3169
3170 /**
3171 * Sets whether this Window should appear at the default location for the
3172 * native windowing system or at the current location (returned by
3173 * <code>getLocation</code>) the next time the Window is made visible.
3174 * This behavior resembles a native window shown without programmatically
3175 * setting its location. Most windowing systems cascade windows if their
3176 * locations are not explicitly set. The actual location is determined once the
3177 * window is shown on the screen.
3178 * <p>
3179 * This behavior can also be enabled by setting the System Property
3180 * "java.awt.Window.locationByPlatform" to "true", though calls to this method
3181 * take precedence.
3182 * <p>
3183 * Calls to <code>setVisible</code>, <code>setLocation</code> and
3184 * <code>setBounds</code> after calling <code>setLocationByPlatform</code> clear
3185 * this property of the Window.
3186 * <p>
3187 * For example, after the following code is executed:
3188 * <pre><blockquote>
3189 * setLocationByPlatform(true);
3190 * setVisible(true);
3191 * boolean flag = isLocationByPlatform();
3192 * </blockquote></pre>
3193 * The window will be shown at platform's default location and
3194 * <code>flag</code> will be <code>false</code>.
3195 * <p>
3196 * In the following sample:
3197 * <pre><blockquote>
3198 * setLocationByPlatform(true);
3199 * setLocation(10, 10);
3200 * boolean flag = isLocationByPlatform();
3201 * setVisible(true);
3202 * </blockquote></pre>
3203 * The window will be shown at (10, 10) and <code>flag</code> will be
3204 * <code>false</code>.
3205 *
3206 * @param locationByPlatform <code>true</code> if this Window should appear
3207 * at the default location, <code>false</code> if at the current location
3208 * @throws <code>IllegalComponentStateException</code> if the window
3209 * is showing on screen and locationByPlatform is <code>true</code>.
3210 * @see #setLocation
3211 * @see #isShowing
3212 * @see #setVisible
3213 * @see #isLocationByPlatform
3214 * @see java.lang.System#getProperty(String)
3215 * @since 1.5
3216 */
3217 public void setLocationByPlatform(boolean locationByPlatform) {
3218 synchronized (getTreeLock()) {
3219 if (locationByPlatform && isShowing()) {
3220 throw new IllegalComponentStateException("The window is showing on screen.");
3221 }
3222 this.locationByPlatform = locationByPlatform;
3223 }
3224 }
3225
3226 /**
3227 * Returns <code>true</code> if this Window will appear at the default location
3228 * for the native windowing system the next time this Window is made visible.
3229 * This method always returns <code>false</code> if the Window is showing on the
3230 * screen.
3231 *
3232 * @return whether this Window will appear at the default location
3233 * @see #setLocationByPlatform
3234 * @see #isShowing
3235 * @since 1.5
3236 */
3237 public boolean isLocationByPlatform() {
3238 synchronized (getTreeLock()) {
3239 return locationByPlatform;
3240 }
3241 }
3242
3243 /**
3244 * {@inheritDoc}
3245 * <p>
3246 * The {@code width} or {@code height} values
3247 * are automatically enlarged if either is less than
3248 * the minimum size as specified by previous call to
3249 * {@code setMinimumSize}.
3250 *
3251 * @see #getBounds
3252 * @see #setLocation(int, int)
3253 * @see #setLocation(Point)
3254 * @see #setSize(int, int)
3255 * @see #setSize(Dimension)
3256 * @see #setMinimumSize
3257 * @see #setLocationByPlatform
3258 * @see #isLocationByPlatform
3259 * @since 1.6
3260 */
3261 public void setBounds(int x, int y, int width, int height) {
3262 synchronized (getTreeLock()) {
3263 if (getBoundsOp() == ComponentPeer.SET_LOCATION ||
3264 getBoundsOp() == ComponentPeer.SET_BOUNDS)
3265 {
3266 locationByPlatform = false;
3267 }
3268 super.setBounds(x, y, width, height);
3269 }
3270 }
3271
3272 /**
3273 * {@inheritDoc}
3274 * <p>
3275 * The {@code r.width} or {@code r.height} values
3276 * will be automatically enlarged if either is less than
3277 * the minimum size as specified by previous call to
3278 * {@code setMinimumSize}.
3279 *
3280 * @see #getBounds
3281 * @see #setLocation(int, int)
3282 * @see #setLocation(Point)
3283 * @see #setSize(int, int)
3284 * @see #setSize(Dimension)
3285 * @see #setMinimumSize
3286 * @see #setLocationByPlatform
3287 * @see #isLocationByPlatform
3288 * @since 1.6
3289 */
3290 public void setBounds(Rectangle r) {
3291 setBounds(r.x, r.y, r.width, r.height);
3292 }
3293
3294 /**
3295 * Determines whether this component will be displayed on the screen.
3296 * @return <code>true</code> if the component and all of its ancestors
3297 * until a toplevel window are visible, <code>false</code> otherwise
3298 */
3299 boolean isRecursivelyVisible() {
3300 // 5079694 fix: for a toplevel to be displayed, its parent doesn't have to be visible.
3301 // We're overriding isRecursivelyVisible to implement this policy.
3302 return visible;
3303 }
3304
3305
3306 // ************************** MIXING CODE *******************************
3307
3308 // A window has a parent, but it does NOT have a container
3309 @Override
3310 final Container getContainer() {
3311 return null;
3312 }
3313
3314 /**
3315 * Applies the shape to the component
3316 * @param shape Shape to be applied to the component
3317 */
3318 @Override
3319 final void applyCompoundShape(Region shape) {
3320 // The shape calculated by mixing code is not intended to be applied
3321 // to windows or frames
3322 }
3323
3324 @Override
3325 final void applyCurrentShape() {
3326 // The shape calculated by mixing code is not intended to be applied
3327 // to windows or frames
3328 }
3329
3330 @Override
3331 final void mixOnReshaping() {
3332 // The shape calculated by mixing code is not intended to be applied
3333 // to windows or frames
3334 }
3335
3336 @Override
3337 final Point getLocationOnWindow() {
3338 return new Point(0, 0);
3339 }
3340
3341 // ****************** END OF MIXING CODE ********************************
3342
3343 } // class Window
3344
3345
3346 /**
3347 * This class is no longer used, but is maintained for Serialization
3348 * backward-compatibility.
3349 */
3350 class FocusManager implements java.io.Serializable {
3351 Container focusRoot;
3352 Component focusOwner;
3353
3354 /*
3355 * JDK 1.1 serialVersionUID
3356 */
3357 static final long serialVersionUID = 2491878825643557906L;
3358 }