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