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