1. /*
  2. * @(#)JRootPane.java 1.48 01/11/29
  3. *
  4. * Copyright 2002 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 javax.accessibility.*;
  11. import java.util.Vector;
  12. import java.io.Serializable;
  13. /**
  14. * The fundamental component in the container hierarchy. In the same way that
  15. * JComponent is fundamental to the JFC/Swing components, JRootPane is fundamental
  16. * to the JFC/Swing window, frame, and pane containers.
  17. * However, while other classes use inheritance to take advantage of JComponent's
  18. * capabilities, the container classes delegate operations to a JRootPane instance.
  19. * Those containers are the heavyweight containers: JFrame, JDialog, JWindow, and
  20. * JApplet, as well as the lightweight container, JInternalFrame.
  21. * <p>
  22. * The following image shows these relationships:
  23. * <p align=center><img src="doc-files/JRootPane-1.gif" HEIGHT=484 WIDTH=629></p>
  24. * The "heavyweight" components (those that delegate to a peer, or native
  25. * component on the host system) are shown with a darker, heavier box. The four
  26. * heavyweight JFC/Swing containers (JFrame, JDialog, JWindow, and JApplet) are
  27. * shown in relation to the AWT classes they extend. These four components are the
  28. * only heavyweight containers in the Swing library. The lightweight container,
  29. * JInternalPane, is also shown. All 5 of these JFC/Swing containers implement the
  30. * RootPaneContainer interface, and they all delegate their operations to a
  31. * JRootPane (shown with a little "handle" on top).
  32. * <blockquote>
  33. * <b>Note:</b> The JComponent method <code>getRootPane</code> can be used to
  34. * obtain the JRootPane that contains a given component.
  35. * </blockquote>
  36. * <table align="right" border="0">
  37. * <tr>
  38. * <td align="center">
  39. * <img src="doc-files/JRootPane-2.gif" HEIGHT=386 WIDTH=349>
  40. * </td>
  41. * </tr>
  42. * </table>
  43. * The diagram at right shows the structure of a JRootPane.
  44. * A JRootpane is made up of a glassPane, an optional menuBar, and
  45. * a contentPane. (The JLayeredPane manages the menuBar and the contentPane.)
  46. * The glassPane sits over the top of everything, where it is in a position
  47. * to intercept mouse movements. Since the glassPane (like the contentPane)
  48. * can be an arbitrary component, it is also possible to set up the
  49. * glassPane for drawing. Lines and images on the glassPane can then range
  50. * over the frames underneath without being limited by their boundaries.
  51. * <p>
  52. * Although the menuBar component is optional, the layeredPane, contentPane,
  53. * and glassPane always exist. Attempting to set them to null generates an
  54. * exception.
  55. * <p>
  56. * The <code>contentPane</code> must be the parent of any children of
  57. * the JRootPane. Rather than adding directly to a JRootPane, like this:
  58. * <PRE>
  59. * rootPane.add(child);
  60. * </PRE>
  61. * You instead add to the contentPane of the JRootPane, like this:
  62. * <PRE>
  63. * rootPane.getContentPane().add(child);
  64. * </PRE>
  65. * The same priniciple holds true for setting layout managers, removing
  66. * components, listing children, etc. All these methods are invoked on
  67. * the <code>contentPane</code> instead of on the JRootPane.
  68. * <blockquote>
  69. * <b>Note:</b> The default layout manager for the <code>contentPane</code> is
  70. * a BorderLayout manager. However, the JRootPane uses a custom LayoutManager.
  71. * So, when you want to change the layout manager for the components you added
  72. * to a JRootPane, be sure to use code like this:<PRE>
  73. * rootPane.getContentPane().setLayout(new BoxLayout());
  74. * </PRE></blockquote>
  75. * If a JMenuBar component is set on the JRootPane, it is positioned
  76. * along the upper edge of the frame. The <code>contentPane</code> is
  77. * adjusted in location and size to fill the remaining area.
  78. * (The JMenuBar and the <code>contentPane</code> are added to the
  79. * <code>layeredPane</code> component at the JLayeredPane.FRAME_CONTENT_LAYER
  80. * layer.)
  81. * <p>
  82. * The <code>layeredPane</code> is the parent of all children in the JRootPane.
  83. * It is an instance of JLayeredPane, which provides the ability to add components
  84. * at several layers. This capability is very useful when working with menu popups,
  85. * dialog boxes, and dragging -- situations in which you need to place a component
  86. * on top of all other components in the pane.
  87. * <p>
  88. * The <code>glassPane</code> sits on top of all other components in the JRootPane.
  89. * That provides a convenient place to draw above all other components, and makes
  90. * it possible to intercept mouse events, which is useful both for dragging and
  91. * for drawing. Developers can use <code>setVisible</code> on the glassPane
  92. * to control when the <code>glassPane</code> displays over the other children.
  93. * By default the <code>glassPane</code> is not visible.
  94. * <p>
  95. * The custom LayoutManager used by JRootPane ensures that:
  96. * <OL>
  97. * <LI>The <code>glassPane</code>, if present, fills the entire viewable
  98. * area of the JRootPane (bounds - insets).
  99. * <LI>The <code>layeredPane</code> fills the entire viewable area of the
  100. * JRootPane. (bounds - insets)
  101. * <LI>The <code>menuBar</code> is positioned at the upper edge of the
  102. * layeredPane().
  103. * <LI>The <code>contentPane</code> fills the entire viewable area,
  104. * minus the MenuBar, if present.
  105. * </OL>
  106. * Any other views in the JRootPane view hierarchy are ignored.
  107. * <p>
  108. * If you replace the LayoutManager of the JRootPane, you are responsible for
  109. * managing all of these views. So ordinarily you will want to be sure that you
  110. * change the layout manager for the <code>contentPane</code> rather than
  111. * for the JRootPane itself!
  112. * <p>
  113. * <strong>Warning:</strong>
  114. * Serialized objects of this class will not be compatible with
  115. * future Swing releases. The current serialization support is appropriate
  116. * for short term storage or RMI between applications running the same
  117. * version of Swing. A future release of Swing will provide support for
  118. * long term persistence.
  119. *
  120. * @see JLayeredPane
  121. * @see JMenuBar
  122. * @see JWindow
  123. * @see JFrame
  124. * @see JDialog
  125. * @see JApplet
  126. * @see JInternalFrame
  127. * @see JComponent
  128. * @see BoxLayout
  129. *
  130. * @see <a href="http://java.sun.com/products/jfc/swingdoc-archive/mixing.html">
  131. * Mixing Heavy and Light Components</a>
  132. *
  133. * @version 1.48 11/29/01
  134. * @author David Kloba
  135. */
  136. /// PENDING(klobad) Who should be opaque in this component?
  137. public class JRootPane extends JComponent implements Accessible {
  138. /** The menu bar. */
  139. protected JMenuBar menuBar;
  140. /** The content pane. */
  141. protected Container contentPane;
  142. /** The layered pane that manages the menu bar and content pane. */
  143. protected JLayeredPane layeredPane;
  144. /**
  145. * The glass pane that overlays the menu bar and content pane,
  146. * so it can intercept mouse movements and such.
  147. */
  148. protected Component glassPane;
  149. /**
  150. * The button that gets activated when the pane has the focus and
  151. * a UI-specific action like pressing the Enter key occurs.
  152. */
  153. protected JButton defaultButton;
  154. /** The action to take when the defaultButton is pressed.
  155. * @see #defaultButton
  156. */
  157. protected DefaultAction defaultPressAction;
  158. /** The action to take when the defaultButton is released.
  159. * @see #defaultButton
  160. */
  161. protected DefaultAction defaultReleaseAction;
  162. /**
  163. * Create a JRootPane, setting up its glassPane, LayeredPane, and contentPane.
  164. */
  165. public JRootPane() {
  166. setGlassPane(createGlassPane());
  167. setLayeredPane(createLayeredPane());
  168. setContentPane(createContentPane());
  169. setLayout(createRootLayout());
  170. setDoubleBuffered(true);
  171. }
  172. /** Called by the constructor methods to create the default layeredPane.
  173. * Bt default it creates a new JLayeredPane.
  174. */
  175. protected JLayeredPane createLayeredPane() {
  176. JLayeredPane p = new JLayeredPane();
  177. p.setName(this.getName()+".layeredPane");
  178. return p;
  179. }
  180. /** Called by the constructor methods to create the default contentPane.
  181. * By default this method creates a new JComponent add sets a
  182. * BorderLayout as its LayoutManager.
  183. */
  184. protected Container createContentPane() {
  185. JComponent c = new JPanel();
  186. c.setName(this.getName()+".contentPane");
  187. c.setLayout(new BorderLayout() {
  188. /* This BorderLayout subclass maps a null constraint to CENTER.
  189. * Although the reference BorderLayout also does this, some VMs
  190. * throw an IllegalArgumentException.
  191. */
  192. public void addLayoutComponent(Component comp, Object constraints) {
  193. if (constraints == null) {
  194. constraints = BorderLayout.CENTER;
  195. }
  196. super.addLayoutComponent(comp, constraints);
  197. }
  198. });
  199. return c;
  200. }
  201. /** Called by the constructor methods to create the default glassPane.
  202. * By default this method creates a new JComponent with visibility
  203. * set to false.
  204. */
  205. protected Component createGlassPane() {
  206. JComponent c = new JPanel();
  207. c.setName(this.getName()+".glassPane");
  208. c.setVisible(false);
  209. ((JPanel)c).setOpaque(false);
  210. return c;
  211. }
  212. /** Called by the constructor methods to create the default layoutManager. */
  213. protected LayoutManager createRootLayout() {
  214. return new RootLayout();
  215. }
  216. /**
  217. * Adds or changes the menu bar used in the layered pane.
  218. * @param menu the JMenuBar to add
  219. */
  220. public void setJMenuBar(JMenuBar menu) {
  221. if(menuBar != null && menuBar.getParent() == layeredPane)
  222. layeredPane.remove(menuBar);
  223. menuBar = menu;
  224. if(menuBar != null)
  225. layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
  226. }
  227. /**
  228. * Specifies the menu bar value.
  229. * @deprecated As of Swing version 1.0.3
  230. * replaced by <code>setJMenuBar(JMenuBar menu)</code>.
  231. */
  232. public void setMenuBar(JMenuBar menu){
  233. if(menuBar != null && menuBar.getParent() == layeredPane)
  234. layeredPane.remove(menuBar);
  235. menuBar = menu;
  236. if(menuBar != null)
  237. layeredPane.add(menuBar, JLayeredPane.FRAME_CONTENT_LAYER);
  238. }
  239. /**
  240. * Returns the menu bar from the layered pane.
  241. * @return the JMenuBar used in the pane
  242. */
  243. public JMenuBar getJMenuBar() { return menuBar; }
  244. /**
  245. * Returns the menu bar value.
  246. * @deprecated As of Swing version 1.0.3
  247. * replaced by <code>getJMenubar()</code>.
  248. */
  249. public JMenuBar getMenuBar() { return menuBar; }
  250. /**
  251. * Sets the content pane -- the container that holds the components
  252. * parented by the root pane.
  253. *
  254. * @param content the Container to use for component-contents
  255. * @exception java.awt.IllegalComponentStateException (a runtime
  256. * exception) if the content pane parameter is null
  257. */
  258. public void setContentPane(Container content) {
  259. if(content == null)
  260. throw new IllegalComponentStateException("contentPane cannot be set to null.");
  261. if(contentPane != null && contentPane.getParent() == layeredPane)
  262. layeredPane.remove(contentPane);
  263. contentPane = content;
  264. layeredPane.add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER);
  265. }
  266. /**
  267. * Returns the content pane -- the container that holds the components
  268. * parented by the root pane.
  269. *
  270. * @return the Container that holds the component-contents
  271. */
  272. public Container getContentPane() { return contentPane; }
  273. // PENDING(klobad) Should this reparent the contentPane and MenuBar?
  274. /**
  275. * Set the layered pane for the root pane. The layered pane
  276. * typically holds a content pane and an optional JMenuBar.
  277. *
  278. * @param layered the JLayeredPane to use.
  279. * @exception java.awt.IllegalComponentStateException (a runtime
  280. * exception) if the layered pane parameter is null
  281. */
  282. public void setLayeredPane(JLayeredPane layered) {
  283. if(layered == null)
  284. throw new IllegalComponentStateException("layeredPane cannot be set to null.");
  285. if(layeredPane != null && layeredPane.getParent() == this)
  286. this.remove(layeredPane);
  287. layeredPane = layered;
  288. this.add(layeredPane, -1);
  289. }
  290. /**
  291. * Get the layered pane used by the root pane. The layered pane
  292. * typically holds a content pane and an optional JMenuBar.
  293. *
  294. * @return the JLayeredPane currently in use
  295. */
  296. public JLayeredPane getLayeredPane() { return layeredPane; }
  297. /**
  298. * Sets a specified Component to be the glass pane for this
  299. * root pane. The glass pane should normally be a lightweight,
  300. * transparent component, because it will be made visible when
  301. * ever the root pane needs to grab input events. For example,
  302. * only one JInternalFrame is ever active when using a
  303. * DefaultDesktop, and any inactive JInternalFrames' glass panes
  304. * are made visible so that clicking anywhere within an inactive
  305. * JInternalFrame can activate it.
  306. * @param glass the Component to use as the glass pane for this
  307. * JRootPane.
  308. */
  309. public void setGlassPane(Component glass) {
  310. if (glass == null) {
  311. throw new NullPointerException("glassPane cannot be set to null.");
  312. }
  313. boolean visible = false;
  314. if (glassPane != null && glassPane.getParent() == this) {
  315. this.remove(glassPane);
  316. visible = glassPane.isVisible();
  317. }
  318. glass.setVisible(visible);
  319. glassPane = glass;
  320. this.add(glassPane, 0);
  321. if (visible) {
  322. repaint();
  323. }
  324. }
  325. /**
  326. * Returns the current glass pane for this JRootPane.
  327. * @return the current glass pane.
  328. * @see #setGlassPane
  329. */
  330. public Component getGlassPane() {
  331. return glassPane;
  332. }
  333. /**
  334. * Make JRootPane be the root of a focus cycle.
  335. * That means that, by default, tabbing within the root
  336. * pane will move between components of the pane,
  337. * but not out of the pane.
  338. * @see JComponent#isFocusCycleRoot
  339. * @return true
  340. */
  341. public boolean isFocusCycleRoot() {
  342. return true;
  343. }
  344. /**
  345. * If a descendant of this JRootPane calls revalidate, validate
  346. * from here on down.
  347. *<p>
  348. * Deferred requests to relayout a component and it's descendants,
  349. * i.e. calls to revalidate(), are pushed upwards to either a JRootPane
  350. * or a JScrollPane because both classes override isValidateRoot() to
  351. * return true.
  352. *
  353. * @see JComponent#isValidateRoot
  354. * @return true
  355. */
  356. public boolean isValidateRoot() {
  357. return true;
  358. }
  359. /**
  360. * Register ourselves with the SystemEventQueueUtils as a new
  361. * root pane.
  362. */
  363. public void addNotify() {
  364. SystemEventQueueUtilities.addRunnableCanvas(this);
  365. super.addNotify();
  366. enableEvents(AWTEvent.KEY_EVENT_MASK);
  367. }
  368. // Note: These links don't work because the target
  369. // class is package private
  370. // @see SystemEventQueueUtilities#addRunnableCanvas
  371. // @see SystemEventQueueUtilities#removeRunnableCanvas
  372. /**
  373. * Unregister ourselves from SystemEventQueueUtils.
  374. */
  375. public void removeNotify() {
  376. SystemEventQueueUtilities.removeRunnableCanvas(this);
  377. super.removeNotify();
  378. }
  379. /**
  380. * Sets the current default button for this JRootPane.
  381. * The default button is the button which will be activated
  382. * when a UI-defined activation event (typically the Enter key)
  383. * occurs in the RootPane regardless of whether or not the button
  384. * has keyboard focus (unless there is another component within
  385. * the RootPane which consumes the activation event, such as a JTextPane).
  386. * For default activation to work, the button must be an enabled
  387. * descendent of the RootPane when activation occurs.
  388. * To remove a default button from this RootPane, set this
  389. * property to null.
  390. *
  391. * @see JButton#isDefaultButton
  392. * @param default the JButton which is to be the default button
  393. */
  394. public void setDefaultButton(JButton defaultButton) {
  395. JButton oldDefault = this.defaultButton;
  396. if (oldDefault != defaultButton) {
  397. this.defaultButton = defaultButton;
  398. if (defaultButton != null) {
  399. if (defaultPressAction == null) {
  400. defaultPressAction = new DefaultAction(this, true);
  401. defaultReleaseAction = new DefaultAction(this, false);
  402. // Eventually we should get the KeyStroke from the UI
  403. // but hardcode it for now....
  404. registerKeyboardAction(defaultPressAction,
  405. KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false),
  406. JComponent.WHEN_IN_FOCUSED_WINDOW);
  407. registerKeyboardAction(defaultReleaseAction,
  408. KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true),
  409. JComponent.WHEN_IN_FOCUSED_WINDOW);
  410. registerKeyboardAction(defaultPressAction,
  411. KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
  412. InputEvent.CTRL_MASK, false),
  413. JComponent.WHEN_IN_FOCUSED_WINDOW);
  414. registerKeyboardAction(defaultReleaseAction,
  415. KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
  416. InputEvent.CTRL_MASK, true),
  417. JComponent.WHEN_IN_FOCUSED_WINDOW);
  418. }
  419. defaultPressAction.setOwner(defaultButton);
  420. defaultReleaseAction.setOwner(defaultButton);
  421. } else {
  422. unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false));
  423. unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true));
  424. unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
  425. InputEvent.CTRL_MASK, false));
  426. unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,
  427. InputEvent.CTRL_MASK, true));
  428. defaultPressAction = null;
  429. defaultReleaseAction = null;
  430. }
  431. if (oldDefault != null) {
  432. oldDefault.repaint();
  433. }
  434. if (defaultButton != null) {
  435. defaultButton.repaint();
  436. }
  437. }
  438. firePropertyChange("defaultButton", oldDefault, defaultButton);
  439. }
  440. /**
  441. * Returns the current default button for this JRootPane.
  442. * @return the JButton which is currently the default button
  443. */
  444. public JButton getDefaultButton() {
  445. return defaultButton;
  446. }
  447. static class DefaultAction extends AbstractAction {
  448. JButton owner;
  449. JRootPane root;
  450. boolean press;
  451. DefaultAction(JRootPane root, boolean press) {
  452. this.root = root;
  453. this.press = press;
  454. }
  455. public void setOwner(JButton owner) {
  456. this.owner = owner;
  457. }
  458. public void actionPerformed(ActionEvent e) {
  459. if (owner != null && SwingUtilities.getRootPane(owner) == root) {
  460. ButtonModel model = owner.getModel();
  461. if (press) {
  462. model.setArmed(true);
  463. model.setPressed(true);
  464. } else {
  465. model.setPressed(false);
  466. }
  467. }
  468. }
  469. public boolean isEnabled() {
  470. return owner.getModel().isEnabled();
  471. }
  472. }
  473. /** Overridden to enforce the position of the glass component as the zero child. */
  474. protected void addImpl(Component comp, Object constraints, int index) {
  475. super.addImpl(comp, constraints, index);
  476. /// We are making sure the glassPane is on top.
  477. if(glassPane != null
  478. && glassPane.getParent() == this
  479. && getComponent(0) != glassPane) {
  480. add(glassPane, 0);
  481. }
  482. }
  483. /**
  484. * Locates the visible child component that contains the specified
  485. * position. The top-most child component is returned in the case
  486. * where there is overlap in the components. If the containing child
  487. * component is a Container, this method will continue searching for
  488. * the deepest nested child component. Components which are not
  489. * visible are ignored during the search.<p>
  490. *
  491. * This method is similar to Container.findComponentAt, except that
  492. * the JRootPane.glassPane is ignored during the search. This
  493. * is needed to to support drag&drop. Since the glassPane is the
  494. * same size as the JRootPane instance, if there's a need to
  495. * test whether the mouse is over the glassPane, just test that it's
  496. * over the JRootPane instead.
  497. *
  498. * @param x the <i>x</i> coordinate
  499. * @param y the <i>y</i. coordinate
  500. * @return null if the component does not contain the position.
  501. * If there is no child component at the requested point and the
  502. * point is within the bounds of this instance, then this
  503. * JRootPane itself is returned.
  504. * @see Container.findComponentAt
  505. * @see Container.getComponentAt
  506. */
  507. public Component findComponentAt(int x, int y) {
  508. if (!contains(x, y)) {
  509. return null;
  510. }
  511. int ncomponents = countComponents();
  512. Component component[] = getComponents();
  513. for (int i = 0 ; i < ncomponents ; i++) {
  514. Component comp = component[i];
  515. if (comp != null) {
  516. if (comp == glassPane) { // don't use equals()
  517. continue;
  518. } else if (comp instanceof Container) {
  519. comp = ((Container)comp).findComponentAt(x - comp.getX(),
  520. y - comp.getY());
  521. } else {
  522. comp = comp.locate(x - comp.getX(), y - comp.getY());
  523. }
  524. if (comp != null && comp.isVisible()) {
  525. return comp;
  526. }
  527. }
  528. }
  529. return this;
  530. }
  531. ///////////////////////////////////////////////////////////////////////////////
  532. //// Begin Inner Classes
  533. ///////////////////////////////////////////////////////////////////////////////
  534. /**
  535. * A custom layout manager that is responsible for the layout of
  536. * layeredPane, glassPane, and menuBar.
  537. * <p>
  538. * <strong>Warning:</strong>
  539. * Serialized objects of this class will not be compatible with
  540. * future Swing releases. The current serialization support is appropriate
  541. * for short term storage or RMI between applications running the same
  542. * version of Swing. A future release of Swing will provide support for
  543. * long term persistence.
  544. */
  545. protected class RootLayout implements LayoutManager2, Serializable
  546. {
  547. /**
  548. * Returns the amount of space the layout would like to have.
  549. *
  550. * @param the Container for which this layout manager is being used
  551. * @return a Dimension object containing the layout's preferred size
  552. */
  553. public Dimension preferredLayoutSize(Container parent) {
  554. Dimension rd, mbd;
  555. Insets i = getInsets();
  556. if(contentPane != null) {
  557. rd = contentPane.getPreferredSize();
  558. } else {
  559. rd = parent.getSize();
  560. }
  561. if(menuBar != null) {
  562. mbd = menuBar.getPreferredSize();
  563. } else {
  564. mbd = new Dimension(0, 0);
  565. }
  566. return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right,
  567. rd.height + mbd.height + i.top + i.bottom);
  568. }
  569. /**
  570. * Returns the minimum amount of space the layout needs.
  571. *
  572. * @param the Container for which this layout manager is being used
  573. * @return a Dimension object containing the layout's minimum size
  574. */
  575. public Dimension minimumLayoutSize(Container parent) {
  576. Dimension rd, mbd;
  577. Insets i = getInsets();
  578. if(contentPane != null) {
  579. rd = contentPane.getMinimumSize();
  580. } else {
  581. rd = parent.getSize();
  582. }
  583. if(menuBar != null) {
  584. mbd = menuBar.getMinimumSize();
  585. } else {
  586. mbd = new Dimension(0, 0);
  587. }
  588. return new Dimension(Math.max(rd.width, mbd.width) + i.left + i.right,
  589. rd.height + mbd.height + i.top + i.bottom);
  590. }
  591. /**
  592. * Returns the maximum amount of space the layout can use.
  593. *
  594. * @param the Container for which this layout manager is being used
  595. * @return a Dimension object containing the layout's maximum size
  596. */
  597. public Dimension maximumLayoutSize(Container target) {
  598. Dimension rd, mbd;
  599. Insets i = getInsets();
  600. if(menuBar != null) {
  601. mbd = menuBar.getMaximumSize();
  602. } else {
  603. mbd = new Dimension(0, 0);
  604. }
  605. if(contentPane != null) {
  606. rd = contentPane.getMaximumSize();
  607. } else {
  608. // This is silly, but should stop an overflow error
  609. rd = new Dimension(Integer.MAX_VALUE,
  610. Integer.MAX_VALUE - i.top - i.bottom - mbd.height - 1);
  611. }
  612. return new Dimension(Math.min(rd.width, mbd.width) + i.left + i.right,
  613. rd.height + mbd.height + i.top + i.bottom);
  614. }
  615. /**
  616. * Instructs the layout manager to perform the layout for the specified
  617. * container.
  618. *
  619. * @param the Container for which this layout manager is being used
  620. */
  621. public void layoutContainer(Container parent) {
  622. Rectangle b = parent.getBounds();
  623. Insets i = getInsets();
  624. int contentY = 0;
  625. int w = b.width - i.right - i.left;
  626. int h = b.height - i.top - i.bottom;
  627. if(layeredPane != null) {
  628. layeredPane.setBounds(i.left, i.top, w, h);
  629. }
  630. if(glassPane != null) {
  631. glassPane.setBounds(i.left, i.top, w, h);
  632. }
  633. // Note: This is laying out the children in the layeredPane,
  634. // technically, these are not our chilren.
  635. if(menuBar != null) {
  636. Dimension mbd = menuBar.getPreferredSize();
  637. menuBar.setBounds(0, 0, w, mbd.height);
  638. contentY += mbd.height;
  639. }
  640. if(contentPane != null) {
  641. contentPane.setBounds(0, contentY, w, h - contentY);
  642. }
  643. }
  644. public void addLayoutComponent(String name, Component comp) {}
  645. public void removeLayoutComponent(Component comp) {}
  646. public void addLayoutComponent(Component comp, Object constraints) {}
  647. public float getLayoutAlignmentX(Container target) { return 0.0f; }
  648. public float getLayoutAlignmentY(Container target) { return 0.0f; }
  649. public void invalidateLayout(Container target) {}
  650. }
  651. /**
  652. * Returns a string representation of this JRootPane. This method
  653. * is intended to be used only for debugging purposes, and the
  654. * content and format of the returned string may vary between
  655. * implementations. The returned string may be empty but may not
  656. * be <code>null</code>.
  657. *
  658. * @return a string representation of this JRootPane.
  659. */
  660. protected String paramString() {
  661. return super.paramString();
  662. }
  663. /////////////////
  664. // Accessibility support
  665. ////////////////
  666. /**
  667. * Get the AccessibleContext associated with this JComponent
  668. *
  669. * @return the AccessibleContext of this JComponent
  670. */
  671. public AccessibleContext getAccessibleContext() {
  672. if (accessibleContext == null) {
  673. accessibleContext = new AccessibleJRootPane();
  674. }
  675. return accessibleContext;
  676. }
  677. /**
  678. * The class used to obtain the accessible role for this object.
  679. * <p>
  680. * <strong>Warning:</strong>
  681. * Serialized objects of this class will not be compatible with
  682. * future Swing releases. The current serialization support is appropriate
  683. * for short term storage or RMI between applications running the same
  684. * version of Swing. A future release of Swing will provide support for
  685. * long term persistence.
  686. */
  687. protected class AccessibleJRootPane extends AccessibleJComponent {
  688. /**
  689. * Get the role of this object.
  690. *
  691. * @return an instance of AccessibleRole describing the role of
  692. * the object
  693. */
  694. public AccessibleRole getAccessibleRole() {
  695. return AccessibleRole.ROOT_PANE;
  696. }
  697. } // inner class AccessibleJRootPane
  698. }