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