1. /*
  2. * @(#)JWindow.java 1.28 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 java.beans.PropertyChangeListener;
  11. import java.util.Locale;
  12. import java.util.Vector;
  13. import java.io.Serializable;
  14. import javax.accessibility.*;
  15. /**
  16. * A JWindow is a container that can be displayed anywhere on the
  17. * user's desktop. It does not have the title bar, window-management buttons,
  18. * or other trimmings associated with a JFrame, but it is still a
  19. * "first-class citizen" of the user's desktop, and can exist anywhere
  20. * on it.
  21. * <p>
  22. * The JWindow component contains a JRootPane as it's only child.
  23. * The contentPane() should be the parent of any children of the JWindow.
  24. * From the older java.awt.Window object you would normally do something like this:<PRE>
  25. * window.add(child);
  26. * </PRE>
  27. * However, using JWindow you would code:<PRE>
  28. * window.getContentPane().add(child);
  29. * </PRE>
  30. * The same is true of setting LayoutManagers, removing components,
  31. * listing children, etc. All these methods should normally be sent to
  32. * the contentPane() instead of the JWindow itself. The contentPane() will
  33. * always be non-null. Attempting to set it to null will cause the JWindow
  34. * to throw an exception. The default contentPane() will have a BorderLayout
  35. * manager set on it.
  36. * <p>
  37. * Please see the JRootPane documentation for a complete description of
  38. * the contentPane(), glassPane(), and layeredPane() components.
  39. * <p>
  40. * For the keyboard keys used by this component in the standard Look and
  41. * Feel (L&F) renditions, see the
  42. * <a href="doc-files/Key-Index.html#JWindow">JWindow</a> key assignments.
  43. * <p>
  44. * <strong>Warning:</strong>
  45. * Serialized objects of this class will not be compatible with
  46. * future Swing releases. The current serialization support is appropriate
  47. * for short term storage or RMI between applications running the same
  48. * version of Swing. A future release of Swing will provide support for
  49. * long term persistence.
  50. *
  51. * @see JRootPane
  52. *
  53. * @beaninfo
  54. * attribute: isContainer true
  55. * attribute: containerDelegate getContentPane
  56. * description: A toplevel window which has no system border or controls.
  57. *
  58. * @version 1.28 11/29/01
  59. * @author David Kloba
  60. */
  61. public class JWindow extends Window implements Accessible, RootPaneContainer
  62. {
  63. /**
  64. * The JRootPane instance that manages the <code>contentPane</code>
  65. * and optional <code>menuBar</code> for this frame, as well as the
  66. * <code>glassPane</code>.
  67. *
  68. * @see #getRootPane
  69. * @see #setRootPane
  70. */
  71. protected JRootPane rootPane;
  72. /**
  73. * If true then calls to <code>add</code> and <code>setLayout</code>
  74. * cause an exception to be thrown.
  75. *
  76. * @see #isRootPaneCheckingEnabled
  77. * @see #setRootPaneCheckingEnabled
  78. */
  79. protected boolean rootPaneCheckingEnabled = false;
  80. /**
  81. * Creates a window with no specified owner.
  82. */
  83. public JWindow() {
  84. this((Frame)null);
  85. }
  86. /**
  87. * Creates a window with the specified owner frame.
  88. *
  89. * @param owner the frame from which the window is displayed
  90. */
  91. public JWindow(Frame owner) {
  92. super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner);
  93. windowInit();
  94. }
  95. /**
  96. * Creates a window with the specified owner window.
  97. *
  98. * @param owner the window from which the window is displayed
  99. */
  100. public JWindow(Window owner) {
  101. super(owner);
  102. windowInit();
  103. }
  104. /** Called by the constructors to init the JWindow properly. */
  105. protected void windowInit() {
  106. setRootPane(createRootPane());
  107. setRootPaneCheckingEnabled(true);
  108. }
  109. /** Called by the constructor methods to create the default rootPane. */
  110. protected JRootPane createRootPane() {
  111. return new JRootPane();
  112. }
  113. /**
  114. * Returns whether calls to <code>add</code> and
  115. * <code>setLayout</code> cause an exception to be thrown.
  116. *
  117. * @return true if <code>add</code> and <code>setLayout</code>
  118. * are checked
  119. *
  120. * @see #addImpl
  121. * @see #setLayout
  122. * @see #setRootPaneCheckingEnabled
  123. */
  124. protected boolean isRootPaneCheckingEnabled() {
  125. return rootPaneCheckingEnabled;
  126. }
  127. /**
  128. * Determines whether calls to <code>add</code> and
  129. * <code>setLayout</code> cause an exception to be thrown.
  130. *
  131. * @param enabled a boolean value, true if checking is to be
  132. * enabled, which cause the exceptions to be thrown
  133. *
  134. * @see #addImpl
  135. * @see #setLayout
  136. * @see #isRootPaneCheckingEnabled
  137. * @beaninfo
  138. * hidden: true
  139. * description: Whether the add and setLayout methods throw exceptions when invoked.
  140. */
  141. protected void setRootPaneCheckingEnabled(boolean enabled) {
  142. rootPaneCheckingEnabled = enabled;
  143. }
  144. /**
  145. * Creates a runtime exception with a message like:
  146. * <pre>
  147. * "Do not use JWindow.add() use JWindow.getContentPane().add() instead"
  148. * </pre>
  149. *
  150. * @param op a String indicating the attempted operation. In the
  151. * example above, the operation string is "add"
  152. */
  153. private Error createRootPaneException(String op) {
  154. String type = getClass().getName();
  155. return new Error(
  156. "Do not use " + type + "." + op + "() use "
  157. + type + ".getContentPane()." + op + "() instead");
  158. }
  159. /**
  160. * By default, children may not be added directly to a this component,
  161. * they must be added to its contentPane instead. For example:
  162. * <pre>
  163. * thisComponent.getContentPane().add(child)
  164. * </pre>
  165. * An attempt to add to directly to this component will cause an
  166. * runtime exception to be thrown. Subclasses can disable this
  167. * behavior.
  168. *
  169. * @see #setRootPaneCheckingEnabled
  170. * @exception Error if called with rootPaneChecking true
  171. */
  172. protected void addImpl(Component comp, Object constraints, int index)
  173. {
  174. if(isRootPaneCheckingEnabled()) {
  175. throw createRootPaneException("add");
  176. }
  177. else {
  178. super.addImpl(comp, constraints, index);
  179. }
  180. }
  181. /**
  182. * Removes the specified component from this container.
  183. * @param comp the component to be removed
  184. * @see #add
  185. */
  186. public void remove(Component comp) {
  187. if (comp == rootPane) {
  188. super.remove(comp);
  189. } else {
  190. // Client mistake, but we need to handle it to avoid a
  191. // common object leak in client applications.
  192. getContentPane().remove(comp);
  193. }
  194. }
  195. /**
  196. * By default the layout of this component may not be set,
  197. * the layout of its contentPane should be set instead.
  198. * For example:
  199. * <pre>
  200. * thisComponent.getContentPane().setLayout(new BorderLayout())
  201. * </pre>
  202. * An attempt to set the layout of this component will cause an
  203. * runtime exception to be thrown. Subclasses can disable this
  204. * behavior.
  205. *
  206. * @see #setRootPaneCheckingEnabled
  207. * @exception Error if called with rootPaneChecking true
  208. */
  209. public void setLayout(LayoutManager manager) {
  210. if(isRootPaneCheckingEnabled()) {
  211. throw createRootPaneException("setLayout");
  212. }
  213. else {
  214. super.setLayout(manager);
  215. }
  216. }
  217. /**
  218. * Returns the rootPane object for this window.
  219. *
  220. * @see #setRootPane
  221. * @see RootPaneContainer#getRootPane
  222. */
  223. public JRootPane getRootPane() {
  224. return rootPane;
  225. }
  226. /**
  227. * Sets the rootPane property. This method is called by the constructor.
  228. *
  229. * @param root the rootPane object for this window
  230. * @see #getRootPane
  231. *
  232. * @beaninfo
  233. * hidden: true
  234. * description: the RootPane object for this window.
  235. */
  236. protected void setRootPane(JRootPane root) {
  237. if(rootPane != null) {
  238. remove(rootPane);
  239. }
  240. rootPane = root;
  241. if(rootPane != null) {
  242. boolean checkingEnabled = isRootPaneCheckingEnabled();
  243. try {
  244. setRootPaneCheckingEnabled(false);
  245. add(rootPane, BorderLayout.CENTER);
  246. }
  247. finally {
  248. setRootPaneCheckingEnabled(checkingEnabled);
  249. }
  250. }
  251. }
  252. /**
  253. * Returns the contentPane object for this window.
  254. *
  255. * @return the Container which is the contentPane
  256. * @see #setContentPane
  257. * @see RootPaneContainer#getContentPane
  258. */
  259. public Container getContentPane() {
  260. return getRootPane().getContentPane();
  261. }
  262. /**
  263. * Sets the contentPane property. This method is called by the constructor.
  264. * @param contentPane the contentPane object for this window
  265. *
  266. * @exception java.awt.IllegalComponentStateException (a runtime
  267. * exception) if the content pane parameter is null
  268. * @see #getContentPane
  269. * @see RootPaneContainer#setContentPane
  270. *
  271. * @beaninfo
  272. * hidden: true
  273. * description: The client area of the window where child
  274. * components are normally inserted.
  275. */
  276. public void setContentPane(Container contentPane) {
  277. getRootPane().setContentPane(contentPane);
  278. }
  279. /**
  280. * Returns the layeredPane object for this window.
  281. *
  282. * @return the JLayeredPane object
  283. * @see #setLayeredPane
  284. * @see RootPaneContainer#getLayeredPane
  285. */
  286. public JLayeredPane getLayeredPane() {
  287. return getRootPane().getLayeredPane();
  288. }
  289. /**
  290. * Sets the layeredPane property. This method is called by the constructor.
  291. * @param layeredPane the layeredPane object for this window
  292. *
  293. * @exception java.awt.IllegalComponentStateException (a runtime
  294. * exception) if the content pane parameter is null
  295. * @see #getLayeredPane
  296. * @see RootPaneContainer#setLayeredPane
  297. *
  298. * @beaninfo
  299. * hidden: true
  300. * description: The pane which holds the various window layers.
  301. */
  302. public void setLayeredPane(JLayeredPane layeredPane) {
  303. getRootPane().setLayeredPane(layeredPane);
  304. }
  305. /**
  306. * Returns the glassPane object for this window.
  307. *
  308. * @return the Component which is the glassPane
  309. * @see #setGlassPane
  310. * @see RootPaneContainer#getGlassPane
  311. */
  312. public Component getGlassPane() {
  313. return getRootPane().getGlassPane();
  314. }
  315. /**
  316. * Sets the glassPane property.
  317. * This method is called by the constructor.
  318. * @param glassPane the glassPane object for this window
  319. *
  320. * @see #getGlassPane
  321. * @see RootPaneContainer#setGlassPane
  322. *
  323. * @beaninfo
  324. * hidden: true
  325. * description: A transparent pane used for menu rendering.
  326. */
  327. public void setGlassPane(Component glassPane) {
  328. getRootPane().setGlassPane(glassPane);
  329. }
  330. /**
  331. * Returns a string representation of this JWindow. This method
  332. * is intended to be used only for debugging purposes, and the
  333. * content and format of the returned string may vary between
  334. * implementations. The returned string may be empty but may not
  335. * be <code>null</code>.
  336. *
  337. * @return a string representation of this JWindow.
  338. */
  339. protected String paramString() {
  340. String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
  341. "true" : "false");
  342. return super.paramString() +
  343. ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
  344. }
  345. /////////////////
  346. // Accessibility support
  347. ////////////////
  348. /** The accessible context property */
  349. protected AccessibleContext accessibleContext = null;
  350. /**
  351. * Get the AccessibleContext associated with this JWindow
  352. *
  353. * @return the AccessibleContext of this JWindow
  354. */
  355. public AccessibleContext getAccessibleContext() {
  356. if (accessibleContext == null) {
  357. accessibleContext = new AccessibleJWindow();
  358. }
  359. return accessibleContext;
  360. }
  361. /**
  362. * The class used to obtain the AccessibleRole for this object.
  363. */
  364. protected class AccessibleJWindow extends AccessibleContext
  365. implements Serializable, AccessibleComponent {
  366. // AccessibleContext methods
  367. //
  368. /**
  369. * Get the role of this object.
  370. *
  371. * @return an instance of AccessibleRole describing the role of the
  372. * object
  373. * @see AccessibleRole
  374. */
  375. public AccessibleRole getAccessibleRole() {
  376. return AccessibleRole.WINDOW;
  377. }
  378. /**
  379. * Get the state of this object.
  380. *
  381. * @return an instance of AccessibleStateSet containing the current
  382. * state set of the object
  383. * @see AccessibleState
  384. */
  385. public AccessibleStateSet getAccessibleStateSet() {
  386. AccessibleStateSet states = SwingUtilities.getAccessibleStateSet(JWindow.this);
  387. if (getFocusOwner() != null) {
  388. states.add(AccessibleState.ACTIVE);
  389. }
  390. return states;
  391. }
  392. /**
  393. * Get the Accessible parent of this object. If the parent of this
  394. * object implements Accessible, this method should simply return
  395. * getParent().
  396. *
  397. * @return the Accessible parent of this object -- can be null if this
  398. * object does not have an Accessible parent
  399. */
  400. public Accessible getAccessibleParent() {
  401. if (accessibleParent != null) {
  402. return accessibleParent;
  403. } else {
  404. Container parent = getParent();
  405. if (parent instanceof Accessible) {
  406. return (Accessible) parent;
  407. }
  408. }
  409. return null;
  410. }
  411. /**
  412. * Get the index of this object in its accessible parent.
  413. *
  414. * @return the index of this object in its parent; -1 if this
  415. * object does not have an accessible parent.
  416. * @see #getAccessibleParent
  417. */
  418. public int getAccessibleIndexInParent() {
  419. return SwingUtilities.getAccessibleIndexInParent(JWindow.this);
  420. }
  421. /**
  422. * Returns the number of accessible children in the object. If all
  423. * of the children of this object implement Accessible, than this
  424. * method should return the number of children of this object.
  425. *
  426. * @return the number of accessible children in the object.
  427. */
  428. public int getAccessibleChildrenCount() {
  429. return SwingUtilities.getAccessibleChildrenCount(JWindow.this);
  430. }
  431. /**
  432. * Return the nth Accessible child of the object.
  433. *
  434. * @param i zero-based index of child
  435. * @return the nth Accessible child of the object
  436. */
  437. public Accessible getAccessibleChild(int i) {
  438. return SwingUtilities.getAccessibleChild(JWindow.this,i);
  439. }
  440. /**
  441. * Return the locale of this object.
  442. *
  443. * @return the locale of this object
  444. */
  445. public Locale getLocale() {
  446. return JWindow.this.getLocale();
  447. }
  448. /**
  449. * Get the AccessibleComponent associated with this object if one
  450. * exists. Otherwise return null.
  451. */
  452. public AccessibleComponent getAccessibleComponent() {
  453. return this;
  454. }
  455. // AccessibleComponent methods
  456. //
  457. /**
  458. * Get the background color of this object.
  459. *
  460. * @return the background color, if supported, of the object;
  461. * otherwise, null
  462. */
  463. public Color getBackground() {
  464. return JWindow.this.getBackground();
  465. }
  466. /**
  467. * Set the background color of this object.
  468. *
  469. * @param c the new Color for the background
  470. */
  471. public void setBackground(Color c) {
  472. JWindow.this.setBackground(c);
  473. }
  474. /**
  475. * Get the foreground color of this object.
  476. *
  477. * @return the foreground color, if supported, of the object;
  478. * otherwise, null
  479. */
  480. public Color getForeground() {
  481. return JWindow.this.getForeground();
  482. }
  483. /**
  484. * Set the foreground color of this object.
  485. *
  486. * @param c the new Color for the foreground
  487. */
  488. public void setForeground(Color c) {
  489. JWindow.this.setForeground(c);
  490. }
  491. /**
  492. * Get the Cursor of this object.
  493. *
  494. * @return the Cursor, if supported, of the object; otherwise, null
  495. */
  496. public Cursor getCursor() {
  497. return JWindow.this.getCursor();
  498. }
  499. /**
  500. * Set the Cursor of this object.
  501. *
  502. * @param c the new Cursor for the object
  503. */
  504. public void setCursor(Cursor cursor) {
  505. JWindow.this.setCursor(cursor);
  506. }
  507. /**
  508. * Get the Font of this object.
  509. *
  510. * @return the Font,if supported, for the object; otherwise, null
  511. */
  512. public Font getFont() {
  513. return JWindow.this.getFont();
  514. }
  515. /**
  516. * Set the Font of this object.
  517. *
  518. * @param f the new Font for the object
  519. */
  520. public void setFont(Font f) {
  521. JWindow.this.setFont(f);
  522. }
  523. /**
  524. * Get the FontMetrics of this object.
  525. *
  526. * @param f the Font
  527. * @return the FontMetrics, if supported, the object; otherwise, null
  528. * @see #getFont
  529. */
  530. public FontMetrics getFontMetrics(Font f) {
  531. return JWindow.this.getFontMetrics(f);
  532. }
  533. /**
  534. * Determine if the object is enabled.
  535. *
  536. * @return true if object is enabled; otherwise, false
  537. */
  538. public boolean isEnabled() {
  539. return JWindow.this.isEnabled();
  540. }
  541. /**
  542. * Set the enabled state of the object.
  543. *
  544. * @param b if true, enables this object; otherwise, disables it
  545. */
  546. public void setEnabled(boolean b) {
  547. JWindow.this.setEnabled(b);
  548. }
  549. /**
  550. * Determine if the object is visible. Note: this means that the
  551. * object intends to be visible; however, it may not in fact be
  552. * showing on the screen because one of the objects that this object
  553. * is contained by is not visible. To determine if an object is
  554. * showing on the screen, use isShowing().
  555. *
  556. * @return true if object is visible; otherwise, false
  557. */
  558. public boolean isVisible() {
  559. return JWindow.this.isVisible();
  560. }
  561. /**
  562. * Set the visible state of the object.
  563. *
  564. * @param b if true, shows this object; otherwise, hides it
  565. */
  566. public void setVisible(boolean b) {
  567. JWindow.this.setVisible(b);
  568. }
  569. /**
  570. * Determine if the object is showing. This is determined by checking
  571. * the visibility of the object and ancestors of the object. Note:
  572. * this will return true even if the object is obscured by another
  573. * (for example, it happens to be underneath a menu that was pulled
  574. * down).
  575. *
  576. * @return true if object is showing; otherwise, false
  577. */
  578. public boolean isShowing() {
  579. return JWindow.this.isShowing();
  580. }
  581. /**
  582. * Checks whether the specified point is within this object's bounds,
  583. * where the point's x and y coordinates are defined to be relative to
  584. * the coordinate system of the object.
  585. *
  586. * @param p the Point relative to the coordinate system of the object
  587. * @return true if object contains Point; otherwise false
  588. */
  589. public boolean contains(Point p) {
  590. return JWindow.this.contains(p);
  591. }
  592. /**
  593. * Returns the location of the object on the screen.
  594. *
  595. * @return location of object on screen -- can be null if this object
  596. * is not on the screen
  597. */
  598. public Point getLocationOnScreen() {
  599. return JWindow.this.getLocationOnScreen();
  600. }
  601. /**
  602. * Gets the location of the object relative to the parent in the form
  603. * of a point specifying the object's top-left corner in the screen's
  604. * coordinate space.
  605. *
  606. * @return An instance of Point representing the top-left corner of
  607. * the objects's bounds in the coordinate space of the screen; null if
  608. * this object or its parent are not on the screen
  609. */
  610. public Point getLocation() {
  611. return JWindow.this.getLocation();
  612. }
  613. /**
  614. * Sets the location of the object relative to the parent.
  615. *
  616. * @param p the Point object specifying the location of the
  617. * object's upper left corner
  618. */
  619. public void setLocation(Point p) {
  620. JWindow.this.setLocation(p);
  621. }
  622. /**
  623. * Gets the bounds of this object in the form of a Rectangle object.
  624. * The bounds specify this object's width, height, and location
  625. * relative to its parent.
  626. *
  627. * @return A rectangle indicating this component's bounds; null if
  628. * this object is not on the screen.
  629. */
  630. public Rectangle getBounds() {
  631. return JWindow.this.getBounds();
  632. }
  633. /**
  634. * Sets the bounds of this object in the form of a Rectangle object.
  635. * The bounds specify this object's width, height, and location
  636. * relative to its parent.
  637. *
  638. * @param A rectangle indicating this component's bounds
  639. */
  640. public void setBounds(Rectangle r) {
  641. JWindow.this.setBounds(r);
  642. }
  643. /**
  644. * Returns the size of this object in the form of a Dimension object.
  645. * The height field of the Dimension object contains this objects's
  646. * height, and the width field of the Dimension object contains this
  647. * object's width.
  648. *
  649. * @return A Dimension object that indicates the size of this
  650. * component; null if this object is not on the screen
  651. */
  652. public Dimension getSize() {
  653. return JWindow.this.getSize();
  654. }
  655. /**
  656. * Resizes this object so that it has width width and height.
  657. *
  658. * @param d - The dimension specifying the new size of the object.
  659. */
  660. public void setSize(Dimension d) {
  661. JWindow.this.setSize(d);
  662. }
  663. /**
  664. * Returns the Accessible child, if one exists, contained at the local
  665. * coordinate Point.
  666. *
  667. * @param p The point defining the top-left corner of the Accessible,
  668. * given in the coordinate space of the object's parent.
  669. * @return the Accessible, if it exists, at the specified location;
  670. * else null
  671. */
  672. public Accessible getAccessibleAt(Point p) {
  673. return SwingUtilities.getAccessibleAt(JWindow.this,p);
  674. }
  675. /**
  676. * Returns whether this object can accept focus or not.
  677. *
  678. * @return true if object can accept focus; otherwise false
  679. */
  680. public boolean isFocusTraversable() {
  681. return JWindow.this.isFocusTraversable();
  682. }
  683. /**
  684. * Requests focus for this object.
  685. */
  686. public void requestFocus() {
  687. JWindow.this.requestFocus();
  688. }
  689. /**
  690. * Adds the specified focus listener to receive focus events from this
  691. * component.
  692. *
  693. * @param l the focus listener
  694. */
  695. public void addFocusListener(FocusListener l) {
  696. JWindow.this.addFocusListener(l);
  697. }
  698. /**
  699. * Removes the specified focus listener so it no longer receives focus
  700. * events from this component.
  701. *
  702. * @param l the focus listener
  703. */
  704. public void removeFocusListener(FocusListener l) {
  705. JWindow.this.removeFocusListener(l);
  706. }
  707. } // inner class AccessibleJWindow
  708. }