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