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.applet.Applet; 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.beans.*; 31 import java.security.AccessController; 32 import javax.accessibility.*; 33 import javax.swing.plaf.RootPaneUI; 34 import java.util.Vector; 35 import java.io.Serializable; 36 import javax.swing.border.*; 37 import sun.awt.AWTAccessor; 38 import sun.security.action.GetBooleanAction; 39 40 41 /** 42 * A lightweight container used behind the scenes by 43 * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>, 44 * <code>JApplet</code>, and <code>JInternalFrame</code>. 45 * For task-oriented information on functionality provided by root panes 46 * see <a href="http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html">How to Use Root Panes</a>, 47 * a section in <em>The Java Tutorial</em>. 48 * 49 * <p> 50 * The following image shows the relationships between 51 * the classes that use root panes. 52 * <p style="text-align:center"><img src="doc-files/JRootPane-1.gif" 53 * alt="The following text describes this graphic." 54 * HEIGHT=484 WIDTH=629></p> 55 * The "heavyweight" components (those that delegate to a peer, or native 56 * component on the host system) are shown with a darker, heavier box. The four 57 * heavyweight JFC/Swing containers (<code>JFrame</code>, <code>JDialog</code>, 58 * <code>JWindow</code>, and <code>JApplet</code>) are 59 * shown in relation to the AWT classes they extend. 60 * These four components are the 61 * only heavyweight containers in the Swing library. The lightweight container 62 * <code>JInternalFrame</code> is also shown. 63 * All five of these JFC/Swing containers implement the 64 * <code>RootPaneContainer</code> interface, 65 * and they all delegate their operations to a 66 * <code>JRootPane</code> (shown with a little "handle" on top). 67 * <blockquote> 68 * <b>Note:</b> The <code>JComponent</code> method <code>getRootPane</code> 69 * can be used to obtain the <code>JRootPane</code> that contains 70 * a given component. 71 * </blockquote> 72 * <table style="float:right" border="0" summary="layout"> 73 * <tr> 74 * <td align="center"> 75 * <img src="doc-files/JRootPane-2.gif" 76 * alt="The following text describes this graphic." HEIGHT=386 WIDTH=349> 77 * </td> 78 * </tr> 79 * </table> 80 * The diagram at right shows the structure of a <code>JRootPane</code>. 81 * A <code>JRootpane</code> is made up of a <code>glassPane</code>, 82 * an optional <code>menuBar</code>, and a <code>contentPane</code>. 83 * (The <code>JLayeredPane</code> manages the <code>menuBar</code> 84 * and the <code>contentPane</code>.) 85 * The <code>glassPane</code> sits over the top of everything, 86 * where it is in a position to intercept mouse movements. 87 * Since the <code>glassPane</code> (like the <code>contentPane</code>) 88 * can be an arbitrary component, it is also possible to set up the 89 * <code>glassPane</code> for drawing. Lines and images on the 90 * <code>glassPane</code> can then range 91 * over the frames underneath without being limited by their boundaries. 92 * <p> 93 * Although the <code>menuBar</code> component is optional, 94 * the <code>layeredPane</code>, <code>contentPane</code>, 95 * and <code>glassPane</code> always exist. 96 * Attempting to set them to <code>null</code> generates an exception. 97 * <p> 98 * To add components to the <code>JRootPane</code> (other than the 99 * optional menu bar), you add the object to the <code>contentPane</code> 100 * of the <code>JRootPane</code>, like this: 101 * <pre> 102 * rootPane.getContentPane().add(child); 103 * </pre> 104 * The same principle holds true for setting layout managers, removing 105 * components, listing children, etc. All these methods are invoked on 106 * the <code>contentPane</code> instead of on the <code>JRootPane</code>. 107 * <blockquote> 108 * <b>Note:</b> The default layout manager for the <code>contentPane</code> is 109 * a <code>BorderLayout</code> manager. However, the <code>JRootPane</code> 110 * uses a custom <code>LayoutManager</code>. 111 * So, when you want to change the layout manager for the components you added 112 * to a <code>JRootPane</code>, be sure to use code like this: 113 * <pre> 114 * rootPane.getContentPane().setLayout(new BoxLayout()); 115 * </pre></blockquote> 116 * If a <code>JMenuBar</code> component is set on the <code>JRootPane</code>, 117 * it is positioned along the upper edge of the frame. 118 * The <code>contentPane</code> is adjusted in location and size to 119 * fill the remaining area. 120 * (The <code>JMenuBar</code> and the <code>contentPane</code> are added to the 121 * <code>layeredPane</code> component at the 122 * <code>JLayeredPane.FRAME_CONTENT_LAYER</code> layer.) 123 * <p> 124 * The <code>layeredPane</code> is the parent of all children in the 125 * <code>JRootPane</code> -- both as the direct parent of the menu and 126 * the grandparent of all components added to the <code>contentPane</code>. 127 * It is an instance of <code>JLayeredPane</code>, 128 * which provides the ability to add components at several layers. 129 * This capability is very useful when working with menu popups, 130 * dialog boxes, and dragging -- situations in which you need to place 131 * a component on top of all other components in the pane. 132 * <p> 133 * The <code>glassPane</code> sits on top of all other components in the 134 * <code>JRootPane</code>. 135 * That provides a convenient place to draw above all other components, 136 * and makes it possible to intercept mouse events, 137 * which is useful both for dragging and for drawing. 138 * Developers can use <code>setVisible</code> on the <code>glassPane</code> 139 * to control when the <code>glassPane</code> displays over the other children. 140 * By default the <code>glassPane</code> is not visible. 141 * <p> 142 * The custom <code>LayoutManager</code> used by <code>JRootPane</code> 143 * ensures that: 144 * <OL> 145 * <LI>The <code>glassPane</code> fills the entire viewable 146 * area of the <code>JRootPane</code> (bounds - insets). 147 * <LI>The <code>layeredPane</code> fills the entire viewable area of the 148 * <code>JRootPane</code>. (bounds - insets) 149 * <LI>The <code>menuBar</code> is positioned at the upper edge of the 150 * <code>layeredPane</code>. 151 * <LI>The <code>contentPane</code> fills the entire viewable area, 152 * minus the <code>menuBar</code>, if present. 153 * </OL> 154 * Any other views in the <code>JRootPane</code> view hierarchy are ignored. 155 * <p> 156 * If you replace the <code>LayoutManager</code> of the <code>JRootPane</code>, 157 * you are responsible for managing all of these views. 158 * So ordinarily you will want to be sure that you 159 * change the layout manager for the <code>contentPane</code> rather than 160 * for the <code>JRootPane</code> itself! 161 * <p> 162 * The painting architecture of Swing requires an opaque 163 * <code>JComponent</code> 164 * to exist in the containment hierarchy above all other components. This is 165 * typically provided by way of the content pane. If you replace the content 166 * pane, it is recommended that you make the content pane opaque 167 * by way of <code>setOpaque(true)</code>. Additionally, if the content pane 168 * overrides <code>paintComponent</code>, it 169 * will need to completely fill in the background in an opaque color in 170 * <code>paintComponent</code>. 171 * <p> 172 * <strong>Warning:</strong> Swing is not thread safe. For more 173 * information see <a 174 * href="package-summary.html#threading">Swing's Threading 175 * Policy</a>. 176 * <p> 177 * <strong>Warning:</strong> 178 * Serialized objects of this class will not be compatible with 179 * future Swing releases. The current serialization support is 180 * appropriate for short term storage or RMI between applications running 181 * the same version of Swing. As of 1.4, support for long term storage 182 * of all JavaBeans™ 183 * has been added to the <code>java.beans</code> package. 184 * Please see {@link java.beans.XMLEncoder}. 185 * 186 * @see JLayeredPane 187 * @see JMenuBar 188 * @see JWindow 189 * @see JFrame 190 * @see JDialog 191 * @see JApplet 192 * @see JInternalFrame 193 * @see JComponent 194 * @see BoxLayout 195 * 196 * @see <a href="http://java.sun.com/products/jfc/tsc/articles/mixing/"> 197 * Mixing Heavy and Light Components</a> 198 * 199 * @author David Kloba 200 * @since 1.2 201 */ 202 /// PENDING(klobad) Who should be opaque in this component? 203 @SuppressWarnings("serial") 204 public class JRootPane extends JComponent implements Accessible { 205 206 private static final String uiClassID = "RootPaneUI"; 207 208 /** 209 * Whether or not we should dump the stack when true double buffering 210 * is disabled. Default is false. 211 */ 212 private static final boolean LOG_DISABLE_TRUE_DOUBLE_BUFFERING; 213 214 /** 215 * Whether or not we should ignore requests to disable true double 216 * buffering. Default is false. 217 */ 218 private static final boolean IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING; 219 220 /** 221 * Constant used for the windowDecorationStyle property. Indicates that 222 * the <code>JRootPane</code> should not provide any sort of 223 * Window decorations. 224 * 225 * @since 1.4 226 */ 227 public static final int NONE = 0; 228 229 /** 230 * Constant used for the windowDecorationStyle property. Indicates that 231 * the <code>JRootPane</code> should provide decorations appropriate for 232 * a Frame. 233 * 234 * @since 1.4 235 */ 236 public static final int FRAME = 1; 237 238 /** 239 * Constant used for the windowDecorationStyle property. Indicates that 240 * the <code>JRootPane</code> should provide decorations appropriate for 241 * a Dialog. 242 * 243 * @since 1.4 244 */ 245 public static final int PLAIN_DIALOG = 2; 246 247 /** 248 * Constant used for the windowDecorationStyle property. Indicates that 249 * the <code>JRootPane</code> should provide decorations appropriate for 250 * a Dialog used to display an informational message. 251 * 252 * @since 1.4 253 */ 254 public static final int INFORMATION_DIALOG = 3; 255 256 /** 257 * Constant used for the windowDecorationStyle property. Indicates that 258 * the <code>JRootPane</code> should provide decorations appropriate for 259 * a Dialog used to display an error message. 260 * 261 * @since 1.4 262 */ 263 public static final int ERROR_DIALOG = 4; 264 265 /** 266 * Constant used for the windowDecorationStyle property. Indicates that 267 * the <code>JRootPane</code> should provide decorations appropriate for 268 * a Dialog used to display a <code>JColorChooser</code>. 269 * 270 * @since 1.4 271 */ 272 public static final int COLOR_CHOOSER_DIALOG = 5; 273 274 /** 275 * Constant used for the windowDecorationStyle property. Indicates that 276 * the <code>JRootPane</code> should provide decorations appropriate for 277 * a Dialog used to display a <code>JFileChooser</code>. 278 * 279 * @since 1.4 280 */ 281 public static final int FILE_CHOOSER_DIALOG = 6; 282 283 /** 284 * Constant used for the windowDecorationStyle property. Indicates that 285 * the <code>JRootPane</code> should provide decorations appropriate for 286 * a Dialog used to present a question to the user. 287 * 288 * @since 1.4 289 */ 290 public static final int QUESTION_DIALOG = 7; 291 292 /** 293 * Constant used for the windowDecorationStyle property. Indicates that 294 * the <code>JRootPane</code> should provide decorations appropriate for 295 * a Dialog used to display a warning message. 296 * 297 * @since 1.4 298 */ 299 public static final int WARNING_DIALOG = 8; 300 301 private int windowDecorationStyle; 302 303 /** The menu bar. */ 304 protected JMenuBar menuBar; 305 306 /** The content pane. */ 307 protected Container contentPane; 308 309 /** The layered pane that manages the menu bar and content pane. */ 310 protected JLayeredPane layeredPane; 311 312 /** 313 * The glass pane that overlays the menu bar and content pane, 314 * so it can intercept mouse movements and such. 315 */ 316 protected Component glassPane; 317 /** 318 * The button that gets activated when the pane has the focus and 319 * a UI-specific action like pressing the <b>Enter</b> key occurs. 320 */ 321 protected JButton defaultButton; 322 /** 323 * As of Java 2 platform v1.3 this unusable field is no longer used. 324 * To override the default button you should replace the <code>Action</code> 325 * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to 326 * the key bindings specification for further details. 327 * 328 * @deprecated As of Java 2 platform v1.3. 329 * @see #defaultButton 330 */ 331 @Deprecated 332 protected DefaultAction defaultPressAction; 333 /** 334 * As of Java 2 platform v1.3 this unusable field is no longer used. 335 * To override the default button you should replace the <code>Action</code> 336 * in the <code>JRootPane</code>'s <code>ActionMap</code>. Please refer to 337 * the key bindings specification for further details. 338 * 339 * @deprecated As of Java 2 platform v1.3. 340 * @see #defaultButton 341 */ 342 @Deprecated 343 protected DefaultAction defaultReleaseAction; 344 345 /** 346 * Whether or not true double buffering should be used. This is typically 347 * true, but may be set to false in special situations. For example, 348 * heavy weight popups (backed by a window) set this to false. 349 */ 350 boolean useTrueDoubleBuffering = true; 351 352 static { 353 LOG_DISABLE_TRUE_DOUBLE_BUFFERING = 354 AccessController.doPrivileged(new GetBooleanAction( 355 "swing.logDoubleBufferingDisable")); 356 IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING = 357 AccessController.doPrivileged(new GetBooleanAction( 358 "swing.ignoreDoubleBufferingDisable")); 359 } 360 361 /** 362 * Creates a <code>JRootPane</code>, setting up its 363 * <code>glassPane</code>, <code>layeredPane</code>, 364 * and <code>contentPane</code>. 365 */ 366 public JRootPane() { 367 setGlassPane(createGlassPane()); 368 setLayeredPane(createLayeredPane()); 369 setContentPane(createContentPane()); 370 setLayout(createRootLayout()); 371 setDoubleBuffered(true); 372 updateUI(); 373 } 374 375 /** 376 * {@inheritDoc} 377 * @since 1.6 378 */ 379 public void setDoubleBuffered(boolean aFlag) { 380 if (isDoubleBuffered() != aFlag) { 381 super.setDoubleBuffered(aFlag); 382 RepaintManager.currentManager(this).doubleBufferingChanged(this); 383 } 384 } 385 386 /** 387 * Returns a constant identifying the type of Window decorations the 388 * <code>JRootPane</code> is providing. 389 * 390 * @return One of <code>NONE</code>, <code>FRAME</code>, 391 * <code>PLAIN_DIALOG</code>, <code>INFORMATION_DIALOG</code>, 392 * <code>ERROR_DIALOG</code>, <code>COLOR_CHOOSER_DIALOG</code>, 393 * <code>FILE_CHOOSER_DIALOG</code>, <code>QUESTION_DIALOG</code> or 394 * <code>WARNING_DIALOG</code>. 395 * @see #setWindowDecorationStyle 396 * @since 1.4 397 */ 398 public int getWindowDecorationStyle() { 399 return windowDecorationStyle; 400 } 401 402 /** 403 * Sets the type of Window decorations (such as borders, widgets for 404 * closing a Window, title ...) the <code>JRootPane</code> should 405 * provide. The default is to provide no Window decorations 406 * (<code>NONE</code>). 407 * <p> 408 * This is only a hint, and some look and feels may not support 409 * this. 410 * This is a bound property. 411 * 412 * @param windowDecorationStyle Constant identifying Window decorations 413 * to provide. 414 * @see JDialog#setDefaultLookAndFeelDecorated 415 * @see JFrame#setDefaultLookAndFeelDecorated 416 * @see LookAndFeel#getSupportsWindowDecorations 417 * @throws IllegalArgumentException if <code>style</code> is 418 * not one of: <code>NONE</code>, <code>FRAME</code>, 419 * <code>PLAIN_DIALOG</code>, <code>INFORMATION_DIALOG</code>, 420 * <code>ERROR_DIALOG</code>, <code>COLOR_CHOOSER_DIALOG</code>, 421 * <code>FILE_CHOOSER_DIALOG</code>, <code>QUESTION_DIALOG</code>, or 422 * <code>WARNING_DIALOG</code>. 423 * @since 1.4 424 * @beaninfo 425 * bound: true 426 * enum: NONE JRootPane.NONE 427 * FRAME JRootPane.FRAME 428 * PLAIN_DIALOG JRootPane.PLAIN_DIALOG 429 * INFORMATION_DIALOG JRootPane.INFORMATION_DIALOG 430 * ERROR_DIALOG JRootPane.ERROR_DIALOG 431 * COLOR_CHOOSER_DIALOG JRootPane.COLOR_CHOOSER_DIALOG 432 * FILE_CHOOSER_DIALOG JRootPane.FILE_CHOOSER_DIALOG 433 * QUESTION_DIALOG JRootPane.QUESTION_DIALOG 434 * WARNING_DIALOG JRootPane.WARNING_DIALOG 435 * expert: true 436 * attribute: visualUpdate true 437 * description: Identifies the type of Window decorations to provide 438 */ 439 public void setWindowDecorationStyle(int windowDecorationStyle) { 440 if (windowDecorationStyle < 0 || 441 windowDecorationStyle > WARNING_DIALOG) { 442 throw new IllegalArgumentException("Invalid decoration style"); 443 } 444 int oldWindowDecorationStyle = getWindowDecorationStyle(); 445 this.windowDecorationStyle = windowDecorationStyle; 446 firePropertyChange("windowDecorationStyle", 447 oldWindowDecorationStyle, 448 windowDecorationStyle); 449 } 450 451 /** 452 * Returns the L&F object that renders this component. 453 * 454 * @return <code>LabelUI</code> object 455 * @since 1.3 456 */ 457 public RootPaneUI getUI() { 458 return (RootPaneUI)ui; 459 } 460 461 /** 462 * Sets the L&F object that renders this component. 463 * 464 * @param ui the <code>LabelUI</code> L&F object 465 * @see UIDefaults#getUI 466 * @beaninfo 467 * bound: true 468 * hidden: true 469 * expert: true 470 * attribute: visualUpdate true 471 * description: The UI object that implements the Component's LookAndFeel. 472 * @since 1.3 473 */ 474 public void setUI(RootPaneUI ui) { 475 super.setUI(ui); 476 } 477 478 479 /** 480 * Resets the UI property to a value from the current look and feel. 481 * 482 * @see JComponent#updateUI 483 */ 484 public void updateUI() { 485 setUI((RootPaneUI)UIManager.getUI(this)); 486 } 487 488 489 /** 490 * Returns a string that specifies the name of the L&F class 491 * that renders this component. 492 * 493 * @return the string "RootPaneUI" 494 * 495 * @see JComponent#getUIClassID 496 * @see UIDefaults#getUI 497 */ 498 public String getUIClassID() { 499 return uiClassID; 500 } 501 502 /** 503 * Called by the constructor methods to create the default 504 * <code>layeredPane</code>. 505 * Bt default it creates a new <code>JLayeredPane</code>. 506 * @return the default <code>layeredPane</code> 507 */ 508 protected JLayeredPane createLayeredPane() { 509 JLayeredPane p = new JLayeredPane(); 510 p.setName(this.getName()+".layeredPane"); 511 return p; 512 } 513 514 /** 515 * Called by the constructor methods to create the default 516 * <code>contentPane</code>. 517 * By default this method creates a new <code>JComponent</code> add sets a 518 * <code>BorderLayout</code> as its <code>LayoutManager</code>. 519 * @return the default <code>contentPane</code> 520 */ 521 protected Container createContentPane() { 522 JComponent c = new JPanel(); 523 c.setName(this.getName()+".contentPane"); 524 c.setLayout(new BorderLayout() { 525 /* This BorderLayout subclass maps a null constraint to CENTER. 526 * Although the reference BorderLayout also does this, some VMs 527 * throw an IllegalArgumentException. 528 */ 529 public void addLayoutComponent(Component comp, Object constraints) { 530 if (constraints == null) { 531 constraints = BorderLayout.CENTER; 532 } 533 super.addLayoutComponent(comp, constraints); 534 } 535 }); 536 return c; 537 } 538 539 /** 540 * Called by the constructor methods to create the default 541 * <code>glassPane</code>. 542 * By default this method creates a new <code>JComponent</code> 543 * with visibility set to false. 544 * @return the default <code>glassPane</code> 545 */ 546 protected Component createGlassPane() { 547 JComponent c = new JPanel(); 548 c.setName(this.getName()+".glassPane"); 549 c.setVisible(false); 550 ((JPanel)c).setOpaque(false); 551 return c; 552 } 553 554 /** 555 * Called by the constructor methods to create the default 556 * <code>layoutManager</code>. 557 * @return the default <code>layoutManager</code>. 558 */ 559 protected LayoutManager createRootLayout() { 560 return new RootLayout(); 561 } 562 563 /** 564 * Adds or changes the menu bar used in the layered pane. 565 * @param menu the <code>JMenuBar</code> to add 566 */ 567 public void setJMenuBar(JMenuBar menu) { 568 if(menuBar != null && menuBar.getParent() == layeredPane) 569 layeredPane.remove(menuBar); 570 menuBar = menu; 571 572 if(menuBar != null) 573 layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER); 574 } 575 576 /** 577 * Specifies the menu bar value. 578 * @deprecated As of Swing version 1.0.3 579 * replaced by <code>setJMenuBar(JMenuBar menu)</code>. 580 * @param menu the <code>JMenuBar</code> to add. 581 */ 582 @Deprecated 583 public void setMenuBar(JMenuBar menu){ 584 if(menuBar != null && menuBar.getParent() == layeredPane) 585 layeredPane.remove(menuBar); 586 menuBar = menu; 587 588 if(menuBar != null) 589 layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER); 590 } 591 592 /** 593 * Returns the menu bar from the layered pane. 594 * @return the <code>JMenuBar</code> used in the pane 595 */ 596 public JMenuBar getJMenuBar() { return menuBar; } 597 598 /** 599 * Returns the menu bar value. 600 * @deprecated As of Swing version 1.0.3 601 * replaced by <code>getJMenuBar()</code>. 602 * @return the <code>JMenuBar</code> used in the pane 603 */ 604 @Deprecated 605 public JMenuBar getMenuBar() { return menuBar; } 606 607 /** 608 * Sets the content pane -- the container that holds the components 609 * parented by the root pane. 610 * <p> 611 * Swing's painting architecture requires an opaque <code>JComponent</code> 612 * in the containment hierarchy. This is typically provided by the 613 * content pane. If you replace the content pane it is recommended you 614 * replace it with an opaque <code>JComponent</code>. 615 * 616 * @param content the <code>Container</code> to use for component-contents 617 * @exception java.awt.IllegalComponentStateException (a runtime 618 * exception) if the content pane parameter is <code>null</code> 619 */ 620 public void setContentPane(Container content) { 621 if(content == null) 622 throw new IllegalComponentStateException("contentPane cannot be set to null."); 623 if(contentPane != null && contentPane.getParent() == layeredPane) 624 layeredPane.remove(contentPane); 625 contentPane = content; 626 627 layeredPane.add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER); 628 } 629 630 /** 631 * Returns the content pane -- the container that holds the components 632 * parented by the root pane. 633 * 634 * @return the <code>Container</code> that holds the component-contents 635 */ 636 public Container getContentPane() { return contentPane; } 637 638 // PENDING(klobad) Should this reparent the contentPane and MenuBar? 639 /** 640 * Sets the layered pane for the root pane. The layered pane 641 * typically holds a content pane and an optional <code>JMenuBar</code>. 642 * 643 * @param layered the <code>JLayeredPane</code> to use 644 * @exception java.awt.IllegalComponentStateException (a runtime 645 * exception) if the layered pane parameter is <code>null</code> 646 */ 647 public void setLayeredPane(JLayeredPane layered) { 648 if(layered == null) 649 throw new IllegalComponentStateException("layeredPane cannot be set to null."); 650 if(layeredPane != null && layeredPane.getParent() == this) 651 this.remove(layeredPane); 652 layeredPane = layered; 653 654 this.add(layeredPane, -1); 655 } 656 /** 657 * Gets the layered pane used by the root pane. The layered pane 658 * typically holds a content pane and an optional <code>JMenuBar</code>. 659 * 660 * @return the <code>JLayeredPane</code> currently in use 661 */ 662 public JLayeredPane getLayeredPane() { return layeredPane; } 663 664 /** 665 * Sets a specified <code>Component</code> to be the glass pane for this 666 * root pane. The glass pane should normally be a lightweight, 667 * transparent component, because it will be made visible when 668 * ever the root pane needs to grab input events. 669 * <p> 670 * The new glass pane's visibility is changed to match that of 671 * the current glass pane. An implication of this is that care 672 * must be taken when you want to replace the glass pane and 673 * make it visible. Either of the following will work: 674 * <pre> 675 * root.setGlassPane(newGlassPane); 676 * newGlassPane.setVisible(true); 677 * </pre> 678 * or: 679 * <pre> 680 * root.getGlassPane().setVisible(true); 681 * root.setGlassPane(newGlassPane); 682 * </pre> 683 * 684 * @param glass the <code>Component</code> to use as the glass pane 685 * for this <code>JRootPane</code> 686 * @exception NullPointerException if the <code>glass</code> parameter is 687 * <code>null</code> 688 */ 689 public void setGlassPane(Component glass) { 690 if (glass == null) { 691 throw new NullPointerException("glassPane cannot be set to null."); 692 } 693 694 AWTAccessor.getComponentAccessor().setMixingCutoutShape(glass, 695 new Rectangle()); 696 697 boolean visible = false; 698 if (glassPane != null && glassPane.getParent() == this) { 699 this.remove(glassPane); 700 visible = glassPane.isVisible(); 701 } 702 703 glass.setVisible(visible); 704 glassPane = glass; 705 this.add(glassPane, 0); 706 if (visible) { 707 repaint(); 708 } 709 } 710 711 /** 712 * Returns the current glass pane for this <code>JRootPane</code>. 713 * @return the current glass pane 714 * @see #setGlassPane 715 */ 716 public Component getGlassPane() { 717 return glassPane; 718 } 719 720 /** 721 * If a descendant of this <code>JRootPane</code> calls 722 * <code>revalidate</code>, validate from here on down. 723 *<p> 724 * Deferred requests to layout a component and its descendents again. 725 * For example, calls to <code>revalidate</code>, are pushed upwards to 726 * either a <code>JRootPane</code> or a <code>JScrollPane</code> 727 * because both classes override <code>isValidateRoot</code> to return true. 728 * 729 * @see JComponent#isValidateRoot 730 * @see java.awt.Container#isValidateRoot 731 * @return true 732 */ 733 @Override 734 public boolean isValidateRoot() { 735 return true; 736 } 737 738 /** 739 * The <code>glassPane</code> and <code>contentPane</code> 740 * have the same bounds, which means <code>JRootPane</code> 741 * does not tiles its children and this should return false. 742 * On the other hand, the <code>glassPane</code> 743 * is normally not visible, and so this can return true if the 744 * <code>glassPane</code> isn't visible. Therefore, the 745 * return value here depends upon the visibility of the 746 * <code>glassPane</code>. 747 * 748 * @return true if this component's children don't overlap 749 */ 750 public boolean isOptimizedDrawingEnabled() { 751 return !glassPane.isVisible(); 752 } 753 754 /** 755 * {@inheritDoc} 756 */ 757 public void addNotify() { 758 super.addNotify(); 759 enableEvents(AWTEvent.KEY_EVENT_MASK); 760 } 761 762 /** 763 * {@inheritDoc} 764 */ 765 public void removeNotify() { 766 super.removeNotify(); 767 } 768 769 770 /** 771 * Sets the <code>defaultButton</code> property, 772 * which determines the current default button for this <code>JRootPane</code>. 773 * The default button is the button which will be activated 774 * when a UI-defined activation event (typically the <b>Enter</b> key) 775 * occurs in the root pane regardless of whether or not the button 776 * has keyboard focus (unless there is another component within 777 * the root pane which consumes the activation event, 778 * such as a <code>JTextPane</code>). 779 * For default activation to work, the button must be an enabled 780 * descendent of the root pane when activation occurs. 781 * To remove a default button from this root pane, set this 782 * property to <code>null</code>. 783 * 784 * @see JButton#isDefaultButton 785 * @param defaultButton the <code>JButton</code> which is to be the default button 786 * 787 * @beaninfo 788 * description: The button activated by default in this root pane 789 */ 790 public void setDefaultButton(JButton defaultButton) { 791 JButton oldDefault = this.defaultButton; 792 793 if (oldDefault != defaultButton) { 794 this.defaultButton = defaultButton; 795 796 if (oldDefault != null) { 797 oldDefault.repaint(); 798 } 799 if (defaultButton != null) { 800 defaultButton.repaint(); 801 } 802 } 803 804 firePropertyChange("defaultButton", oldDefault, defaultButton); 805 } 806 807 /** 808 * Returns the value of the <code>defaultButton</code> property. 809 * @return the <code>JButton</code> which is currently the default button 810 * @see #setDefaultButton 811 */ 812 public JButton getDefaultButton() { 813 return defaultButton; 814 } 815 816 final void setUseTrueDoubleBuffering(boolean useTrueDoubleBuffering) { 817 this.useTrueDoubleBuffering = useTrueDoubleBuffering; 818 } 819 820 final boolean getUseTrueDoubleBuffering() { 821 return useTrueDoubleBuffering; 822 } 823 824 final void disableTrueDoubleBuffering() { 825 if (useTrueDoubleBuffering) { 826 if (!IGNORE_DISABLE_TRUE_DOUBLE_BUFFERING) { 827 if (LOG_DISABLE_TRUE_DOUBLE_BUFFERING) { 828 System.out.println("Disabling true double buffering for " + 829 this); 830 Thread.dumpStack(); 831 } 832 useTrueDoubleBuffering = false; 833 RepaintManager.currentManager(this). 834 doubleBufferingChanged(this); 835 } 836 } 837 } 838 839 @SuppressWarnings("serial") 840 static class DefaultAction extends AbstractAction { 841 JButton owner; 842 JRootPane root; 843 boolean press; 844 DefaultAction(JRootPane root, boolean press) { 845 this.root = root; 846 this.press = press; 847 } 848 public void setOwner(JButton owner) { 849 this.owner = owner; 850 } 851 public void actionPerformed(ActionEvent e) { 852 if (owner != null && SwingUtilities.getRootPane(owner) == root) { 853 ButtonModel model = owner.getModel(); 854 if (press) { 855 model.setArmed(true); 856 model.setPressed(true); 857 } else { 858 model.setPressed(false); 859 } 860 } 861 } 862 public boolean isEnabled() { 863 return owner.getModel().isEnabled(); 864 } 865 } 866 867 868 /** 869 * Overridden to enforce the position of the glass component as 870 * the zero child. 871 * 872 * @param comp the component to be enhanced 873 * @param constraints the constraints to be respected 874 * @param index the index 875 */ 876 protected void addImpl(Component comp, Object constraints, int index) { 877 super.addImpl(comp, constraints, index); 878 879 /// We are making sure the glassPane is on top. 880 if(glassPane != null 881 && glassPane.getParent() == this 882 && getComponent(0) != glassPane) { 883 add(glassPane, 0); 884 } 885 } 886 887 888 /////////////////////////////////////////////////////////////////////////////// 889 //// Begin Inner Classes 890 /////////////////////////////////////////////////////////////////////////////// 891 892 893 /** 894 * A custom layout manager that is responsible for the layout of 895 * layeredPane, glassPane, and menuBar. 896 * <p> 897 * <strong>Warning:</strong> 898 * Serialized objects of this class will not be compatible with 899 * future Swing releases. The current serialization support is 900 * appropriate for short term storage or RMI between applications running 901 * the same version of Swing. As of 1.4, support for long term storage 902 * of all JavaBeans™ 903 * has been added to the <code>java.beans</code> package. 904 * Please see {@link java.beans.XMLEncoder}. 905 */ 906 @SuppressWarnings("serial") 907 protected class RootLayout implements LayoutManager2, Serializable 908 { 909 /** 910 * Returns the amount of space the layout would like to have. 911 * 912 * @param parent the Container for which this layout manager 913 * is being used 914 * @return a Dimension object containing the layout's preferred size 915 */ 916 public Dimension preferredLayoutSize(Container parent) { 917 Dimension rd, mbd; 918 Insets i = getInsets(); 919 920 if(contentPane != null) { 921 rd = contentPane.getPreferredSize(); 922 } else { 923 rd = parent.getSize(); 924 } 925 if(menuBar != null && menuBar.isVisible()) { 926 mbd = menuBar.getPreferredSize(); 927 } else { 928 mbd = new Dimension(0, 0); 929 } 930 return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right, 931 rd.height + mbd.height + i.top + i.bottom); 932 } 933 934 /** 935 * Returns the minimum amount of space the layout needs. 936 * 937 * @param parent the Container for which this layout manager 938 * is being used 939 * @return a Dimension object containing the layout's minimum size 940 */ 941 public Dimension minimumLayoutSize(Container parent) { 942 Dimension rd, mbd; 943 Insets i = getInsets(); 944 if(contentPane != null) { 945 rd = contentPane.getMinimumSize(); 946 } else { 947 rd = parent.getSize(); 948 } 949 if(menuBar != null && menuBar.isVisible()) { 950 mbd = menuBar.getMinimumSize(); 951 } else { 952 mbd = new Dimension(0, 0); 953 } 954 return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right, 955 rd.height + mbd.height + i.top + i.bottom); 956 } 957 958 /** 959 * Returns the maximum amount of space the layout can use. 960 * 961 * @param target the Container for which this layout manager 962 * is being used 963 * @return a Dimension object containing the layout's maximum size 964 */ 965 public Dimension maximumLayoutSize(Container target) { 966 Dimension rd, mbd; 967 Insets i = getInsets(); 968 if(menuBar != null && menuBar.isVisible()) { 969 mbd = menuBar.getMaximumSize(); 970 } else { 971 mbd = new Dimension(0, 0); 972 } 973 if(contentPane != null) { 974 rd = contentPane.getMaximumSize(); 975 } else { 976 // This is silly, but should stop an overflow error 977 rd = new Dimension(Integer.MAX_VALUE, 978 Integer.MAX_VALUE - i.top - i.bottom - mbd.height - 1); 979 } 980 return new Dimension(Math.min(rd.width, mbd.width) + i.left + i.right, 981 rd.height + mbd.height + i.top + i.bottom); 982 } 983 984 /** 985 * Instructs the layout manager to perform the layout for the specified 986 * container. 987 * 988 * @param parent the Container for which this layout manager 989 * is being used 990 */ 991 public void layoutContainer(Container parent) { 992 Rectangle b = parent.getBounds(); 993 Insets i = getInsets(); 994 int contentY = 0; 995 int w = b.width - i.right - i.left; 996 int h = b.height - i.top - i.bottom; 997 998 if(layeredPane != null) { 999 layeredPane.setBounds(i.left, i.top, w, h); 1000 } 1001 if(glassPane != null) { 1002 glassPane.setBounds(i.left, i.top, w, h); 1003 } 1004 // Note: This is laying out the children in the layeredPane, 1005 // technically, these are not our children. 1006 if(menuBar != null && menuBar.isVisible()) { 1007 Dimension mbd = menuBar.getPreferredSize(); 1008 menuBar.setBounds(0, 0, w, mbd.height); 1009 contentY += mbd.height; 1010 } 1011 if(contentPane != null) { 1012 contentPane.setBounds(0, contentY, w, h - contentY); 1013 } 1014 } 1015 1016 public void addLayoutComponent(String name, Component comp) {} 1017 public void removeLayoutComponent(Component comp) {} 1018 public void addLayoutComponent(Component comp, Object constraints) {} 1019 public float getLayoutAlignmentX(Container target) { return 0.0f; } 1020 public float getLayoutAlignmentY(Container target) { return 0.0f; } 1021 public void invalidateLayout(Container target) {} 1022 } 1023 1024 /** 1025 * Returns a string representation of this <code>JRootPane</code>. 1026 * This method is intended to be used only for debugging purposes, 1027 * and the content and format of the returned string may vary between 1028 * implementations. The returned string may be empty but may not 1029 * be <code>null</code>. 1030 * 1031 * @return a string representation of this <code>JRootPane</code>. 1032 */ 1033 protected String paramString() { 1034 return super.paramString(); 1035 } 1036 1037 ///////////////// 1038 // Accessibility support 1039 //////////////// 1040 1041 /** 1042 * Gets the <code>AccessibleContext</code> associated with this 1043 * <code>JRootPane</code>. For root panes, the 1044 * <code>AccessibleContext</code> takes the form of an 1045 * <code>AccessibleJRootPane</code>. 1046 * A new <code>AccessibleJRootPane</code> instance is created if necessary. 1047 * 1048 * @return an <code>AccessibleJRootPane</code> that serves as the 1049 * <code>AccessibleContext</code> of this <code>JRootPane</code> 1050 */ 1051 public AccessibleContext getAccessibleContext() { 1052 if (accessibleContext == null) { 1053 accessibleContext = new AccessibleJRootPane(); 1054 } 1055 return accessibleContext; 1056 } 1057 1058 /** 1059 * This class implements accessibility support for the 1060 * <code>JRootPane</code> class. It provides an implementation of the 1061 * Java Accessibility API appropriate to root pane user-interface elements. 1062 * <p> 1063 * <strong>Warning:</strong> 1064 * Serialized objects of this class will not be compatible with 1065 * future Swing releases. The current serialization support is 1066 * appropriate for short term storage or RMI between applications running 1067 * the same version of Swing. As of 1.4, support for long term storage 1068 * of all JavaBeans™ 1069 * has been added to the <code>java.beans</code> package. 1070 * Please see {@link java.beans.XMLEncoder}. 1071 */ 1072 @SuppressWarnings("serial") 1073 protected class AccessibleJRootPane extends AccessibleJComponent { 1074 /** 1075 * Get the role of this object. 1076 * 1077 * @return an instance of AccessibleRole describing the role of 1078 * the object 1079 */ 1080 public AccessibleRole getAccessibleRole() { 1081 return AccessibleRole.ROOT_PANE; 1082 } 1083 1084 /** 1085 * Returns the number of accessible children of the object. 1086 * 1087 * @return the number of accessible children of the object. 1088 */ 1089 public int getAccessibleChildrenCount() { 1090 return super.getAccessibleChildrenCount(); 1091 } 1092 1093 /** 1094 * Returns the specified Accessible child of the object. The Accessible 1095 * children of an Accessible object are zero-based, so the first child 1096 * of an Accessible child is at index 0, the second child is at index 1, 1097 * and so on. 1098 * 1099 * @param i zero-based index of child 1100 * @return the Accessible child of the object 1101 * @see #getAccessibleChildrenCount 1102 */ 1103 public Accessible getAccessibleChild(int i) { 1104 return super.getAccessibleChild(i); 1105 } 1106 } // inner class AccessibleJRootPane 1107 }