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