1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package javax.swing; 26 27 import java.awt.*; 28 import java.awt.event.*; 29 import java.beans.JavaBean; 30 import java.beans.BeanProperty; 31 32 import javax.accessibility.*; 33 34 /** 35 * A <code>JWindow</code> is a container that can be displayed anywhere on the 36 * user's desktop. It does not have the title bar, window-management buttons, 37 * or other trimmings associated with a <code>JFrame</code>, but it is still a 38 * "first-class citizen" of the user's desktop, and can exist anywhere 39 * on it. 40 * <p> 41 * The <code>JWindow</code> component contains a <code>JRootPane</code> 42 * as its only child. The <code>contentPane</code> should be the parent 43 * of any children of the <code>JWindow</code>. 44 * As a convenience, the {@code add}, {@code remove}, and {@code setLayout} 45 * methods of this class are overridden, so that they delegate calls 46 * to the corresponding methods of the {@code ContentPane}. 47 * For example, you can add a child component to a window as follows: 48 * <pre> 49 * window.add(child); 50 * </pre> 51 * And the child will be added to the contentPane. 52 * The <code>contentPane</code> will always be non-<code>null</code>. 53 * Attempting to set it to <code>null</code> will cause the <code>JWindow</code> 54 * to throw an exception. The default <code>contentPane</code> will have a 55 * <code>BorderLayout</code> manager set on it. 56 * Refer to {@link javax.swing.RootPaneContainer} 57 * for details on adding, removing and setting the <code>LayoutManager</code> 58 * of a <code>JWindow</code>. 59 * <p> 60 * Please see the {@link JRootPane} documentation for a complete description of 61 * the <code>contentPane</code>, <code>glassPane</code>, and 62 * <code>layeredPane</code> components. 63 * <p> 64 * In a multi-screen environment, you can create a <code>JWindow</code> 65 * on a different screen device. See {@link java.awt.Window} for more 66 * information. 67 * <p> 68 * <strong>Warning:</strong> Swing is not thread safe. For more 69 * information see <a 70 * href="package-summary.html#threading">Swing's Threading 71 * Policy</a>. 72 * <p> 73 * <strong>Warning:</strong> 74 * Serialized objects of this class will not be compatible with 75 * future Swing releases. The current serialization support is 76 * appropriate for short term storage or RMI between applications running 77 * the same version of Swing. As of 1.4, support for long term storage 78 * of all JavaBeans™ 79 * has been added to the <code>java.beans</code> package. 80 * Please see {@link java.beans.XMLEncoder}. 81 * 82 * @see JRootPane 83 * 84 * @author David Kloba 85 * @since 1.2 86 */ 87 @JavaBean(defaultProperty = "accessibleContext", description = "A toplevel window which has no system border or controls.") 88 @SwingContainer(delegate = "getContentPane") 89 @SuppressWarnings("serial") 90 public class JWindow extends Window implements Accessible, 91 RootPaneContainer, 92 TransferHandler.HasGetTransferHandler 93 { 94 /** 95 * The <code>JRootPane</code> instance that manages the 96 * <code>contentPane</code> 97 * and optional <code>menuBar</code> for this frame, as well as the 98 * <code>glassPane</code>. 99 * 100 * @see #getRootPane 101 * @see #setRootPane 102 */ 103 protected JRootPane rootPane; 104 105 /** 106 * If true then calls to <code>add</code> and <code>setLayout</code> 107 * will be forwarded to the <code>contentPane</code>. This is initially 108 * false, but is set to true when the <code>JWindow</code> is constructed. 109 * 110 * @see #isRootPaneCheckingEnabled 111 * @see #setRootPaneCheckingEnabled 112 * @see javax.swing.RootPaneContainer 113 */ 114 protected boolean rootPaneCheckingEnabled = false; 115 116 /** 117 * The <code>TransferHandler</code> for this window. 118 */ 119 private TransferHandler transferHandler; 120 121 /** 122 * Creates a window with no specified owner. This window will not be 123 * focusable. 124 * <p> 125 * This constructor sets the component's locale property to the value 126 * returned by <code>JComponent.getDefaultLocale</code>. 127 * 128 * @throws HeadlessException if 129 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 130 * @see java.awt.GraphicsEnvironment#isHeadless 131 * @see #isFocusableWindow 132 * @see JComponent#getDefaultLocale 133 */ 134 public JWindow() { 135 this((Frame)null); 136 } 137 138 /** 139 * Creates a window with the specified <code>GraphicsConfiguration</code> 140 * of a screen device. This window will not be focusable. 141 * <p> 142 * This constructor sets the component's locale property to the value 143 * returned by <code>JComponent.getDefaultLocale</code>. 144 * 145 * @param gc the <code>GraphicsConfiguration</code> that is used 146 * to construct the new window with; if gc is <code>null</code>, 147 * the system default <code>GraphicsConfiguration</code> 148 * is assumed 149 * @throws HeadlessException If 150 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 151 * @throws IllegalArgumentException if <code>gc</code> is not from 152 * a screen device. 153 * 154 * @see java.awt.GraphicsEnvironment#isHeadless 155 * @see #isFocusableWindow 156 * @see JComponent#getDefaultLocale 157 * 158 * @since 1.3 159 */ 160 public JWindow(GraphicsConfiguration gc) { 161 this(null, gc); 162 super.setFocusableWindowState(false); 163 } 164 165 /** 166 * Creates a window with the specified owner frame. 167 * If <code>owner</code> is <code>null</code>, the shared owner 168 * will be used and this window will not be focusable. Also, 169 * this window will not be focusable unless its owner is showing 170 * on the screen. 171 * <p> 172 * This constructor sets the component's locale property to the value 173 * returned by <code>JComponent.getDefaultLocale</code>. 174 * 175 * @param owner the frame from which the window is displayed 176 * @throws HeadlessException if GraphicsEnvironment.isHeadless() 177 * returns true. 178 * @see java.awt.GraphicsEnvironment#isHeadless 179 * @see #isFocusableWindow 180 * @see JComponent#getDefaultLocale 181 */ 182 public JWindow(Frame owner) { 183 super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner); 184 if (owner == null) { 185 WindowListener ownerShutdownListener = 186 SwingUtilities.getSharedOwnerFrameShutdownListener(); 187 addWindowListener(ownerShutdownListener); 188 } 189 windowInit(); 190 } 191 192 /** 193 * Creates a window with the specified owner window. This window 194 * will not be focusable unless its owner is showing on the screen. 195 * If <code>owner</code> is <code>null</code>, the shared owner 196 * will be used and this window will not be focusable. 197 * <p> 198 * This constructor sets the component's locale property to the value 199 * returned by <code>JComponent.getDefaultLocale</code>. 200 * 201 * @param owner the window from which the window is displayed 202 * @throws HeadlessException if 203 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 204 * @see java.awt.GraphicsEnvironment#isHeadless 205 * @see #isFocusableWindow 206 * @see JComponent#getDefaultLocale 207 */ 208 public JWindow(Window owner) { 209 super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() : 210 owner); 211 if (owner == null) { 212 WindowListener ownerShutdownListener = 213 SwingUtilities.getSharedOwnerFrameShutdownListener(); 214 addWindowListener(ownerShutdownListener); 215 } 216 windowInit(); 217 } 218 219 /** 220 * Creates a window with the specified owner window and 221 * <code>GraphicsConfiguration</code> of a screen device. If 222 * <code>owner</code> is <code>null</code>, the shared owner will be used 223 * and this window will not be focusable. 224 * <p> 225 * This constructor sets the component's locale property to the value 226 * returned by <code>JComponent.getDefaultLocale</code>. 227 * 228 * @param owner the window from which the window is displayed 229 * @param gc the <code>GraphicsConfiguration</code> that is used 230 * to construct the new window with; if gc is <code>null</code>, 231 * the system default <code>GraphicsConfiguration</code> 232 * is assumed, unless <code>owner</code> is also null, in which 233 * case the <code>GraphicsConfiguration</code> from the 234 * shared owner frame will be used. 235 * @throws HeadlessException if 236 * <code>GraphicsEnvironment.isHeadless()</code> returns true. 237 * @throws IllegalArgumentException if <code>gc</code> is not from 238 * a screen device. 239 * 240 * @see java.awt.GraphicsEnvironment#isHeadless 241 * @see #isFocusableWindow 242 * @see JComponent#getDefaultLocale 243 * 244 * @since 1.3 245 */ 246 public JWindow(Window owner, GraphicsConfiguration gc) { 247 super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() : 248 owner, gc); 249 if (owner == null) { 250 WindowListener ownerShutdownListener = 251 SwingUtilities.getSharedOwnerFrameShutdownListener(); 252 addWindowListener(ownerShutdownListener); 253 } 254 windowInit(); 255 } 256 257 /** 258 * Called by the constructors to init the <code>JWindow</code> properly. 259 */ 260 protected void windowInit() { 261 setLocale( JComponent.getDefaultLocale() ); 262 setRootPane(createRootPane()); 263 setRootPaneCheckingEnabled(true); 264 sun.awt.SunToolkit.checkAndSetPolicy(this); 265 } 266 267 /** 268 * Called by the constructor methods to create the default 269 * <code>rootPane</code>. 270 * 271 * @return a new {@code JRootPane} 272 */ 273 protected JRootPane createRootPane() { 274 JRootPane rp = new JRootPane(); 275 // NOTE: this uses setOpaque vs LookAndFeel.installProperty as there 276 // is NO reason for the RootPane not to be opaque. For painting to 277 // work the contentPane must be opaque, therefor the RootPane can 278 // also be opaque. 279 rp.setOpaque(true); 280 return rp; 281 } 282 283 /** 284 * Returns whether calls to <code>add</code> and 285 * <code>setLayout</code> are forwarded to the <code>contentPane</code>. 286 * 287 * @return true if <code>add</code> and <code>setLayout</code> 288 * are forwarded; false otherwise 289 * 290 * @see #addImpl 291 * @see #setLayout 292 * @see #setRootPaneCheckingEnabled 293 * @see javax.swing.RootPaneContainer 294 */ 295 protected boolean isRootPaneCheckingEnabled() { 296 return rootPaneCheckingEnabled; 297 } 298 299 /** 300 * Sets the {@code transferHandler} property, which is a mechanism to 301 * support transfer of data into this component. Use {@code null} 302 * if the component does not support data transfer operations. 303 * <p> 304 * If the system property {@code suppressSwingDropSupport} is {@code false} 305 * (the default) and the current drop target on this component is either 306 * {@code null} or not a user-set drop target, this method will change the 307 * drop target as follows: If {@code newHandler} is {@code null} it will 308 * clear the drop target. If not {@code null} it will install a new 309 * {@code DropTarget}. 310 * <p> 311 * Note: When used with {@code JWindow}, {@code TransferHandler} only 312 * provides data import capability, as the data export related methods 313 * are currently typed to {@code JComponent}. 314 * <p> 315 * Please see 316 * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html"> 317 * How to Use Drag and Drop and Data Transfer</a>, a section in 318 * <em>The Java Tutorial</em>, for more information. 319 * 320 * @param newHandler the new {@code TransferHandler} 321 * 322 * @see TransferHandler 323 * @see #getTransferHandler 324 * @see java.awt.Component#setDropTarget 325 * @since 1.6 326 */ 327 @BeanProperty(hidden = true, description 328 = "Mechanism for transfer of data into the component") 329 public void setTransferHandler(TransferHandler newHandler) { 330 TransferHandler oldHandler = transferHandler; 331 transferHandler = newHandler; 332 SwingUtilities.installSwingDropTargetAsNecessary(this, transferHandler); 333 firePropertyChange("transferHandler", oldHandler, newHandler); 334 } 335 336 /** 337 * Gets the <code>transferHandler</code> property. 338 * 339 * @return the value of the <code>transferHandler</code> property 340 * 341 * @see TransferHandler 342 * @see #setTransferHandler 343 * @since 1.6 344 */ 345 public TransferHandler getTransferHandler() { 346 return transferHandler; 347 } 348 349 /** 350 * Calls <code>paint(g)</code>. This method was overridden to 351 * prevent an unnecessary call to clear the background. 352 * 353 * @param g the <code>Graphics</code> context in which to paint 354 */ 355 public void update(Graphics g) { 356 paint(g); 357 } 358 359 /** 360 * Sets whether calls to <code>add</code> and 361 * <code>setLayout</code> are forwarded to the <code>contentPane</code>. 362 * 363 * @param enabled true if <code>add</code> and <code>setLayout</code> 364 * are forwarded, false if they should operate directly on the 365 * <code>JWindow</code>. 366 * 367 * @see #addImpl 368 * @see #setLayout 369 * @see #isRootPaneCheckingEnabled 370 * @see javax.swing.RootPaneContainer 371 */ 372 @BeanProperty(hidden = true, description 373 = "Whether the add and setLayout methods are forwarded") 374 protected void setRootPaneCheckingEnabled(boolean enabled) { 375 rootPaneCheckingEnabled = enabled; 376 } 377 378 379 /** 380 * Adds the specified child <code>Component</code>. 381 * This method is overridden to conditionally forward calls to the 382 * <code>contentPane</code>. 383 * By default, children are added to the <code>contentPane</code> instead 384 * of the frame, refer to {@link javax.swing.RootPaneContainer} for 385 * details. 386 * 387 * @param comp the component to be enhanced 388 * @param constraints the constraints to be respected 389 * @param index the index 390 * @exception IllegalArgumentException if <code>index</code> is invalid 391 * @exception IllegalArgumentException if adding the container's parent 392 * to itself 393 * @exception IllegalArgumentException if adding a window to a container 394 * 395 * @see #setRootPaneCheckingEnabled 396 * @see javax.swing.RootPaneContainer 397 */ 398 protected void addImpl(Component comp, Object constraints, int index) 399 { 400 if(isRootPaneCheckingEnabled()) { 401 getContentPane().add(comp, constraints, index); 402 } 403 else { 404 super.addImpl(comp, constraints, index); 405 } 406 } 407 408 /** 409 * Removes the specified component from the container. If 410 * <code>comp</code> is not the <code>rootPane</code>, this will forward 411 * the call to the <code>contentPane</code>. This will do nothing if 412 * <code>comp</code> is not a child of the <code>JWindow</code> or 413 * <code>contentPane</code>. 414 * 415 * @param comp the component to be removed 416 * @throws NullPointerException if <code>comp</code> is null 417 * @see #add 418 * @see javax.swing.RootPaneContainer 419 */ 420 public void remove(Component comp) { 421 if (comp == rootPane) { 422 super.remove(comp); 423 } else { 424 getContentPane().remove(comp); 425 } 426 } 427 428 429 /** 430 * Sets the <code>LayoutManager</code>. 431 * Overridden to conditionally forward the call to the 432 * <code>contentPane</code>. 433 * Refer to {@link javax.swing.RootPaneContainer} for 434 * more information. 435 * 436 * @param manager the <code>LayoutManager</code> 437 * @see #setRootPaneCheckingEnabled 438 * @see javax.swing.RootPaneContainer 439 */ 440 public void setLayout(LayoutManager manager) { 441 if(isRootPaneCheckingEnabled()) { 442 getContentPane().setLayout(manager); 443 } 444 else { 445 super.setLayout(manager); 446 } 447 } 448 449 450 /** 451 * Returns the <code>rootPane</code> object for this window. 452 * @return the <code>rootPane</code> property for this window 453 * 454 * @see #setRootPane 455 * @see RootPaneContainer#getRootPane 456 */ 457 @BeanProperty(bound = false, hidden = true, description 458 = "the RootPane object for this window.") 459 public JRootPane getRootPane() { 460 return rootPane; 461 } 462 463 464 /** 465 * Sets the new <code>rootPane</code> object for this window. 466 * This method is called by the constructor. 467 * 468 * @param root the new <code>rootPane</code> property 469 * @see #getRootPane 470 */ 471 protected void setRootPane(JRootPane root) { 472 if(rootPane != null) { 473 remove(rootPane); 474 } 475 rootPane = root; 476 if(rootPane != null) { 477 boolean checkingEnabled = isRootPaneCheckingEnabled(); 478 try { 479 setRootPaneCheckingEnabled(false); 480 add(rootPane, BorderLayout.CENTER); 481 } 482 finally { 483 setRootPaneCheckingEnabled(checkingEnabled); 484 } 485 } 486 } 487 488 489 /** 490 * Returns the <code>Container</code> which is the <code>contentPane</code> 491 * for this window. 492 * 493 * @return the <code>contentPane</code> property 494 * @see #setContentPane 495 * @see RootPaneContainer#getContentPane 496 */ 497 public Container getContentPane() { 498 return getRootPane().getContentPane(); 499 } 500 501 /** 502 * Sets the <code>contentPane</code> property for this window. 503 * This method is called by the constructor. 504 * 505 * @param contentPane the new <code>contentPane</code> 506 * 507 * @exception IllegalComponentStateException (a runtime 508 * exception) if the content pane parameter is <code>null</code> 509 * @see #getContentPane 510 * @see RootPaneContainer#setContentPane 511 */ 512 @BeanProperty(bound = false, hidden = true, description 513 = "The client area of the window where child components are normally inserted.") 514 public void setContentPane(Container contentPane) { 515 getRootPane().setContentPane(contentPane); 516 } 517 518 /** 519 * Returns the <code>layeredPane</code> object for this window. 520 * 521 * @return the <code>layeredPane</code> property 522 * @see #setLayeredPane 523 * @see RootPaneContainer#getLayeredPane 524 */ 525 public JLayeredPane getLayeredPane() { 526 return getRootPane().getLayeredPane(); 527 } 528 529 /** 530 * Sets the <code>layeredPane</code> property. 531 * This method is called by the constructor. 532 * 533 * @param layeredPane the new <code>layeredPane</code> object 534 * 535 * @exception IllegalComponentStateException (a runtime 536 * exception) if the content pane parameter is <code>null</code> 537 * @see #getLayeredPane 538 * @see RootPaneContainer#setLayeredPane 539 */ 540 @BeanProperty(bound = false, hidden = true, description 541 = "The pane which holds the various window layers.") 542 public void setLayeredPane(JLayeredPane layeredPane) { 543 getRootPane().setLayeredPane(layeredPane); 544 } 545 546 /** 547 * Returns the <code>glassPane Component</code> for this window. 548 * 549 * @return the <code>glassPane</code> property 550 * @see #setGlassPane 551 * @see RootPaneContainer#getGlassPane 552 */ 553 public Component getGlassPane() { 554 return getRootPane().getGlassPane(); 555 } 556 557 /** 558 * Sets the <code>glassPane</code> property. 559 * This method is called by the constructor. 560 * @param glassPane the <code>glassPane</code> object for this window 561 * 562 * @see #getGlassPane 563 * @see RootPaneContainer#setGlassPane 564 */ 565 @BeanProperty(bound = false, hidden = true, description 566 = "A transparent pane used for menu rendering.") 567 public void setGlassPane(Component glassPane) { 568 getRootPane().setGlassPane(glassPane); 569 } 570 571 /** 572 * {@inheritDoc} 573 * 574 * @since 1.6 575 */ 576 @BeanProperty(bound = false) 577 public Graphics getGraphics() { 578 JComponent.getGraphicsInvoked(this); 579 return super.getGraphics(); 580 } 581 582 /** 583 * Repaints the specified rectangle of this component within 584 * <code>time</code> milliseconds. Refer to <code>RepaintManager</code> 585 * for details on how the repaint is handled. 586 * 587 * @param time maximum time in milliseconds before update 588 * @param x the <i>x</i> coordinate 589 * @param y the <i>y</i> coordinate 590 * @param width the width 591 * @param height the height 592 * @see RepaintManager 593 * @since 1.6 594 */ 595 public void repaint(long time, int x, int y, int width, int height) { 596 if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) { 597 RepaintManager.currentManager(this).addDirtyRegion( 598 this, x, y, width, height); 599 } 600 else { 601 super.repaint(time, x, y, width, height); 602 } 603 } 604 605 /** 606 * Returns a string representation of this <code>JWindow</code>. 607 * This method 608 * is intended to be used only for debugging purposes, and the 609 * content and format of the returned string may vary between 610 * implementations. The returned string may be empty but may not 611 * be <code>null</code>. 612 * 613 * @return a string representation of this <code>JWindow</code> 614 */ 615 protected String paramString() { 616 String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ? 617 "true" : "false"); 618 619 return super.paramString() + 620 ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString; 621 } 622 623 624 ///////////////// 625 // Accessibility support 626 //////////////// 627 628 /** The accessible context property. */ 629 protected AccessibleContext accessibleContext = null; 630 631 /** 632 * Gets the AccessibleContext associated with this JWindow. 633 * For JWindows, the AccessibleContext takes the form of an 634 * AccessibleJWindow. 635 * A new AccessibleJWindow instance is created if necessary. 636 * 637 * @return an AccessibleJWindow that serves as the 638 * AccessibleContext of this JWindow 639 */ 640 public AccessibleContext getAccessibleContext() { 641 if (accessibleContext == null) { 642 accessibleContext = new AccessibleJWindow(); 643 } 644 return accessibleContext; 645 } 646 647 648 /** 649 * This class implements accessibility support for the 650 * <code>JWindow</code> class. It provides an implementation of the 651 * Java Accessibility API appropriate to window user-interface 652 * elements. 653 */ 654 @SuppressWarnings("serial") 655 protected class AccessibleJWindow extends AccessibleAWTWindow { 656 // everything is in the new parent, AccessibleAWTWindow 657 } 658 659 }