1. /*
  2. * @(#)JWindow.java 1.60 03/12/19
  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.PropertyChangeListener;
  11. import java.util.Locale;
  12. import java.util.Vector;
  13. import java.io.Serializable;
  14. import javax.accessibility.*;
  15. /**
  16. * A <code>JWindow</code> 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 <code>JFrame</code>, 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 <code>JWindow</code> component contains a <code>JRootPane</code>
  23. * as its only child. The <code>contentPane</code> should be the parent
  24. * of any children of the <code>JWindow</code>.
  25. * As a conveniance <code>add</code> and its variants, <code>remove</code> and
  26. * <code>setLayout</code> have been overridden to forward to the
  27. * <code>contentPane</code> as necessary. This means you can write:
  28. * <pre>
  29. * window.add(child);
  30. * </pre>
  31. * And the child will be added to the contentPane.
  32. * The <code>contentPane</code> will always be non-<code>null</code>.
  33. * Attempting to set it to <code>null</code> will cause the <code>JWindow</code>
  34. * to throw an exception. The default <code>contentPane</code> will have a
  35. * <code>BorderLayout</code> manager set on it.
  36. * Refer to {@link javax.swing.RootPaneContainer}
  37. * for details on adding, removing and setting the <code>LayoutManager</code>
  38. * of a <code>JWindow</code>.
  39. * <p>
  40. * Please see the {@link JRootPane} documentation for a complete description of
  41. * the <code>contentPane</code>, <code>glassPane</code>, and
  42. * <code>layeredPane</code> components.
  43. * <p>
  44. * In a multi-screen environment, you can create a <code>JWindow</code>
  45. * on a different screen device. See {@link java.awt.Window} for more
  46. * information.
  47. * <p>
  48. * <strong>Warning:</strong>
  49. * Serialized objects of this class will not be compatible with
  50. * future Swing releases. The current serialization support is
  51. * appropriate for short term storage or RMI between applications running
  52. * the same version of Swing. As of 1.4, support for long term storage
  53. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  54. * has been added to the <code>java.beans</code> package.
  55. * Please see {@link java.beans.XMLEncoder}.
  56. *
  57. * @see JRootPane
  58. *
  59. * @beaninfo
  60. * attribute: isContainer true
  61. * attribute: containerDelegate getContentPane
  62. * description: A toplevel window which has no system border or controls.
  63. *
  64. * @version 1.60 12/19/03
  65. * @author David Kloba
  66. */
  67. public class JWindow extends Window implements Accessible, RootPaneContainer
  68. {
  69. /**
  70. * The <code>JRootPane</code> instance that manages the
  71. * <code>contentPane</code>
  72. * and optional <code>menuBar</code> for this frame, as well as the
  73. * <code>glassPane</code>.
  74. *
  75. * @see #getRootPane
  76. * @see #setRootPane
  77. */
  78. protected JRootPane rootPane;
  79. /**
  80. * If true then calls to <code>add</code> and <code>setLayout</code>
  81. * will be forwarded to the <code>contentPane</code>. This is initially
  82. * false, but is set to true when the <code>JWindow</code> is constructed.
  83. *
  84. * @see #isRootPaneCheckingEnabled
  85. * @see #setRootPaneCheckingEnabled
  86. * @see javax.swing.RootPaneContainer
  87. */
  88. protected boolean rootPaneCheckingEnabled = false;
  89. /**
  90. * Creates a window with no specified owner. This window will not be
  91. * focusable.
  92. * <p>
  93. * This constructor sets the component's locale property to the value
  94. * returned by <code>JComponent.getDefaultLocale</code>.
  95. *
  96. * @throws HeadlessException if
  97. * <code>GraphicsEnvironment.isHeadless()</code> returns true.
  98. * @see java.awt.GraphicsEnvironment#isHeadless
  99. * @see #isFocusableWindow
  100. * @see JComponent#getDefaultLocale
  101. */
  102. public JWindow() {
  103. this((Frame)null);
  104. }
  105. /**
  106. * Creates a window with the specified <code>GraphicsConfiguration</code>
  107. * of a screen device. This window will not be focusable.
  108. * <p>
  109. * This constructor sets the component's locale property to the value
  110. * returned by <code>JComponent.getDefaultLocale</code>.
  111. *
  112. * @param gc the <code>GraphicsConfiguration</code> that is used
  113. * to construct the new window with; if gc is <code>null</code>,
  114. * the system default <code>GraphicsConfiguration</code>
  115. * is assumed
  116. * @throws HeadlessException If
  117. * <code>GraphicsEnvironment.isHeadless()</code> returns true.
  118. * @throws IllegalArgumentException if <code>gc</code> is not from
  119. * a screen device.
  120. *
  121. * @see java.awt.GraphicsEnvironment#isHeadless
  122. * @see #isFocusableWindow
  123. * @see JComponent#getDefaultLocale
  124. *
  125. * @since 1.3
  126. */
  127. public JWindow(GraphicsConfiguration gc) {
  128. this(null, gc);
  129. super.setFocusableWindowState(false);
  130. }
  131. /**
  132. * Creates a window with the specified owner frame.
  133. * If <code>owner</code> is <code>null</code>, the shared owner
  134. * will be used and this window will not be focusable. Also,
  135. * this window will not be focusable unless its owner is showing
  136. * on the screen.
  137. * <p>
  138. * This constructor sets the component's locale property to the value
  139. * returned by <code>JComponent.getDefaultLocale</code>.
  140. *
  141. * @param owner the frame from which the window is displayed
  142. * @throws HeadlessException if GraphicsEnvironment.isHeadless()
  143. * returns true.
  144. * @see java.awt.GraphicsEnvironment#isHeadless
  145. * @see #isFocusableWindow
  146. * @see JComponent#getDefaultLocale
  147. */
  148. public JWindow(Frame owner) {
  149. super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner);
  150. if (owner == null) {
  151. WindowListener ownerShutdownListener =
  152. (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener();
  153. addWindowListener(ownerShutdownListener);
  154. }
  155. windowInit();
  156. }
  157. /**
  158. * Creates a window with the specified owner window. This window
  159. * will not be focusable unless its owner is showing on the screen.
  160. * If <code>owner</code> is <code>null</code>, the shared owner
  161. * will be used and this window will not be focusable.
  162. * <p>
  163. * This constructor sets the component's locale property to the value
  164. * returned by <code>JComponent.getDefaultLocale</code>.
  165. *
  166. * @param owner the window from which the window is displayed
  167. * @throws HeadlessException if
  168. * <code>GraphicsEnvironment.isHeadless()</code> returns true.
  169. * @see java.awt.GraphicsEnvironment#isHeadless
  170. * @see #isFocusableWindow
  171. * @see JComponent#getDefaultLocale
  172. */
  173. public JWindow(Window owner) {
  174. super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() :
  175. owner);
  176. if (owner == null) {
  177. WindowListener ownerShutdownListener =
  178. (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener();
  179. addWindowListener(ownerShutdownListener);
  180. }
  181. windowInit();
  182. }
  183. /**
  184. * Creates a window with the specified owner window and
  185. * <code>GraphicsConfiguration</code> of a screen device. If
  186. * <code>owner</code> is <code>null</code>, the shared owner will be used
  187. * and this window will not be focusable.
  188. * <p>
  189. * This constructor sets the component's locale property to the value
  190. * returned by <code>JComponent.getDefaultLocale</code>.
  191. *
  192. * @param owner the window from which the window is displayed
  193. * @param gc the <code>GraphicsConfiguration</code> that is used
  194. * to construct the new window with; if gc is <code>null</code>,
  195. * the system default <code>GraphicsConfiguration</code>
  196. * is assumed, unless <code>owner</code> is also null, in which
  197. * case the <code>GraphicsConfiguration</code> from the
  198. * shared owner frame will be used.
  199. * @throws HeadlessException if
  200. * <code>GraphicsEnvironment.isHeadless()</code> returns true.
  201. * @throws IllegalArgumentException if <code>gc</code> is not from
  202. * a screen device.
  203. *
  204. * @see java.awt.GraphicsEnvironment#isHeadless
  205. * @see #isFocusableWindow
  206. * @see JComponent#getDefaultLocale
  207. *
  208. * @since 1.3
  209. */
  210. public JWindow(Window owner, GraphicsConfiguration gc) {
  211. super(owner == null ? (Window)SwingUtilities.getSharedOwnerFrame() :
  212. owner, gc);
  213. if (owner == null) {
  214. WindowListener ownerShutdownListener =
  215. (WindowListener)SwingUtilities.getSharedOwnerFrameShutdownListener();
  216. addWindowListener(ownerShutdownListener);
  217. }
  218. windowInit();
  219. }
  220. /**
  221. * Called by the constructors to init the <code>JWindow</code> properly.
  222. */
  223. protected void windowInit() {
  224. setLocale( JComponent.getDefaultLocale() );
  225. setRootPane(createRootPane());
  226. setRootPaneCheckingEnabled(true);
  227. sun.awt.SunToolkit.checkAndSetPolicy(this, true);
  228. }
  229. /**
  230. * Called by the constructor methods to create the default
  231. * <code>rootPane</code>.
  232. */
  233. protected JRootPane createRootPane() {
  234. JRootPane rp = new JRootPane();
  235. // NOTE: this uses setOpaque vs LookAndFeel.installProperty as there
  236. // is NO reason for the RootPane not to be opaque. For painting to
  237. // work the contentPane must be opaque, therefor the RootPane can
  238. // also be opaque.
  239. rp.setOpaque(true);
  240. return rp;
  241. }
  242. /**
  243. * Returns whether calls to <code>add</code> and
  244. * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
  245. *
  246. * @return true if <code>add</code> and <code>setLayout</code>
  247. * are fowarded; false otherwise
  248. *
  249. * @see #addImpl
  250. * @see #setLayout
  251. * @see #setRootPaneCheckingEnabled
  252. * @see javax.swing.RootPaneContainer
  253. */
  254. protected boolean isRootPaneCheckingEnabled() {
  255. return rootPaneCheckingEnabled;
  256. }
  257. /**
  258. * Calls <code>paint(g)</code>. This method was overridden to
  259. * prevent an unnecessary call to clear the background.
  260. *
  261. * @param g the <code>Graphics</code> context in which to paint
  262. */
  263. public void update(Graphics g) {
  264. paint(g);
  265. }
  266. /**
  267. * Sets whether calls to <code>add</code> and
  268. * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
  269. *
  270. * @param enabled true if <code>add</code> and <code>setLayout</code>
  271. * are forwarded, false if they should operate directly on the
  272. * <code>JWindow</code>.
  273. *
  274. * @see #addImpl
  275. * @see #setLayout
  276. * @see #isRootPaneCheckingEnabled
  277. * @see javax.swing.RootPaneContainer
  278. * @beaninfo
  279. * hidden: true
  280. * description: Whether the add and setLayout methods are forwarded
  281. */
  282. protected void setRootPaneCheckingEnabled(boolean enabled) {
  283. rootPaneCheckingEnabled = enabled;
  284. }
  285. /**
  286. * Adds the specified child <code>Component</code>.
  287. * This method is overridden to conditionally forwad calls to the
  288. * <code>contentPane</code>.
  289. * By default, children are added to the <code>contentPane</code> instead
  290. * of the frame, refer to {@link javax.swing.RootPaneContainer} for
  291. * details.
  292. *
  293. * @param comp the component to be enhanced
  294. * @param constraints the constraints to be respected
  295. * @param index the index
  296. * @exception IllegalArgumentException if <code>index</code> is invalid
  297. * @exception IllegalArgumentException if adding the container's parent
  298. * to itself
  299. * @exception IllegalArgumentException if adding a window to a container
  300. *
  301. * @see #setRootPaneCheckingEnabled
  302. * @see javax.swing.RootPaneContainer
  303. */
  304. protected void addImpl(Component comp, Object constraints, int index)
  305. {
  306. if(isRootPaneCheckingEnabled()) {
  307. getContentPane().add(comp, constraints, index);
  308. }
  309. else {
  310. super.addImpl(comp, constraints, index);
  311. }
  312. }
  313. /**
  314. * Removes the specified component from the container. If
  315. * <code>comp</code> is not the <code>rootPane</code>, this will forward
  316. * the call to the <code>contentPane</code>. This will do nothing if
  317. * <code>comp</code> is not a child of the <code>JWindow</code> or
  318. * <code>contentPane</code>.
  319. *
  320. * @param comp the component to be removed
  321. * @throws NullPointerException if <code>comp</code> is null
  322. * @see #add
  323. * @see javax.swing.RootPaneContainer
  324. */
  325. public void remove(Component comp) {
  326. if (comp == rootPane) {
  327. super.remove(comp);
  328. } else {
  329. getContentPane().remove(comp);
  330. }
  331. }
  332. /**
  333. * Sets the <code>LayoutManager</code>.
  334. * Overridden to conditionally forward the call to the
  335. * <code>contentPane</code>.
  336. * Refer to {@link javax.swing.RootPaneContainer} for
  337. * more information.
  338. *
  339. * @param manager the <code>LayoutManager</code>
  340. * @see #setRootPaneCheckingEnabled
  341. * @see javax.swing.RootPaneContainer
  342. */
  343. public void setLayout(LayoutManager manager) {
  344. if(isRootPaneCheckingEnabled()) {
  345. getContentPane().setLayout(manager);
  346. }
  347. else {
  348. super.setLayout(manager);
  349. }
  350. }
  351. /**
  352. * Returns the <code>rootPane</code> object for this window.
  353. * @return the <code>rootPane</code> property for this window
  354. *
  355. * @see #setRootPane
  356. * @see RootPaneContainer#getRootPane
  357. */
  358. public JRootPane getRootPane() {
  359. return rootPane;
  360. }
  361. /**
  362. * Sets the new <code>rootPane</code> object for this window.
  363. * This method is called by the constructor.
  364. *
  365. * @param root the new <code>rootPane</code> property
  366. * @see #getRootPane
  367. *
  368. * @beaninfo
  369. * hidden: true
  370. * description: the RootPane object for this window.
  371. */
  372. protected void setRootPane(JRootPane root) {
  373. if(rootPane != null) {
  374. remove(rootPane);
  375. }
  376. rootPane = root;
  377. if(rootPane != null) {
  378. boolean checkingEnabled = isRootPaneCheckingEnabled();
  379. try {
  380. setRootPaneCheckingEnabled(false);
  381. add(rootPane, BorderLayout.CENTER);
  382. }
  383. finally {
  384. setRootPaneCheckingEnabled(checkingEnabled);
  385. }
  386. }
  387. }
  388. /**
  389. * Returns the <code>Container</code> which is the <code>contentPane</code>
  390. * for this window.
  391. *
  392. * @return the <code>contentPane</code> property
  393. * @see #setContentPane
  394. * @see RootPaneContainer#getContentPane
  395. */
  396. public Container getContentPane() {
  397. return getRootPane().getContentPane();
  398. }
  399. /**
  400. * Sets the <code>contentPane</code> property for this window.
  401. * This method is called by the constructor.
  402. *
  403. * @param contentPane the new <code>contentPane</code>
  404. *
  405. * @exception IllegalComponentStateException (a runtime
  406. * exception) if the content pane parameter is <code>null</code>
  407. * @see #getContentPane
  408. * @see RootPaneContainer#setContentPane
  409. *
  410. * @beaninfo
  411. * hidden: true
  412. * description: The client area of the window where child
  413. * components are normally inserted.
  414. */
  415. public void setContentPane(Container contentPane) {
  416. getRootPane().setContentPane(contentPane);
  417. }
  418. /**
  419. * Returns the <code>layeredPane</code> object for this window.
  420. *
  421. * @return the <code>layeredPane</code> property
  422. * @see #setLayeredPane
  423. * @see RootPaneContainer#getLayeredPane
  424. */
  425. public JLayeredPane getLayeredPane() {
  426. return getRootPane().getLayeredPane();
  427. }
  428. /**
  429. * Sets the <code>layeredPane</code> property.
  430. * This method is called by the constructor.
  431. *
  432. * @param layeredPane the new <code>layeredPane</code> object
  433. *
  434. * @exception IllegalComponentStateException (a runtime
  435. * exception) if the content pane parameter is <code>null</code>
  436. * @see #getLayeredPane
  437. * @see RootPaneContainer#setLayeredPane
  438. *
  439. * @beaninfo
  440. * hidden: true
  441. * description: The pane which holds the various window layers.
  442. */
  443. public void setLayeredPane(JLayeredPane layeredPane) {
  444. getRootPane().setLayeredPane(layeredPane);
  445. }
  446. /**
  447. * Returns the <code>glassPane Component</code> for this window.
  448. *
  449. * @return the <code>glassPane</code> property
  450. * @see #setGlassPane
  451. * @see RootPaneContainer#getGlassPane
  452. */
  453. public Component getGlassPane() {
  454. return getRootPane().getGlassPane();
  455. }
  456. /**
  457. * Sets the <code>glassPane</code> property.
  458. * This method is called by the constructor.
  459. * @param glassPane the <code>glassPane</code> object for this window
  460. *
  461. * @see #getGlassPane
  462. * @see RootPaneContainer#setGlassPane
  463. *
  464. * @beaninfo
  465. * hidden: true
  466. * description: A transparent pane used for menu rendering.
  467. */
  468. public void setGlassPane(Component glassPane) {
  469. getRootPane().setGlassPane(glassPane);
  470. }
  471. /**
  472. * Returns a string representation of this <code>JWindow</code>.
  473. * This method
  474. * is intended to be used only for debugging purposes, and the
  475. * content and format of the returned string may vary between
  476. * implementations. The returned string may be empty but may not
  477. * be <code>null</code>.
  478. *
  479. * @return a string representation of this <code>JWindow</code>
  480. */
  481. protected String paramString() {
  482. String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
  483. "true" : "false");
  484. return super.paramString() +
  485. ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
  486. }
  487. /////////////////
  488. // Accessibility support
  489. ////////////////
  490. /** The accessible context property. */
  491. protected AccessibleContext accessibleContext = null;
  492. /**
  493. * Gets the AccessibleContext associated with this JWindow.
  494. * For JWindows, the AccessibleContext takes the form of an
  495. * AccessibleJWindow.
  496. * A new AccessibleJWindow instance is created if necessary.
  497. *
  498. * @return an AccessibleJWindow that serves as the
  499. * AccessibleContext of this JWindow
  500. */
  501. public AccessibleContext getAccessibleContext() {
  502. if (accessibleContext == null) {
  503. accessibleContext = new AccessibleJWindow();
  504. }
  505. return accessibleContext;
  506. }
  507. /**
  508. * This class implements accessibility support for the
  509. * <code>JWindow</code> class. It provides an implementation of the
  510. * Java Accessibility API appropriate to window user-interface
  511. * elements.
  512. */
  513. protected class AccessibleJWindow extends AccessibleAWTWindow {
  514. // everything is in the new parent, AccessibleAWTWindow
  515. }
  516. }