1. /*
  2. * @(#)JWindow.java 1.37 01/02/09
  3. *
  4. * Copyright 1997-2001 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing;
  11. import java.awt.*;
  12. import java.awt.event.*;
  13. import java.beans.PropertyChangeListener;
  14. import java.util.Locale;
  15. import java.util.Vector;
  16. import java.io.Serializable;
  17. import javax.accessibility.*;
  18. /**
  19. * A <code>JWindow</code> is a container that can be displayed anywhere on the
  20. * user's desktop. It does not have the title bar, window-management buttons,
  21. * or other trimmings associated with a <code>JFrame</code>, but it is still a
  22. * "first-class citizen" of the user's desktop, and can exist anywhere
  23. * on it.
  24. * <p>
  25. * The <code>JWindow</code> component contains a <code>JRootPane</code>
  26. * as it's only child.
  27. * The <code>contentPane</code> should be the parent of any children of the
  28. * <code>JWindow</code>.
  29. * From the older <code>java.awt.Window</code> object you would normally do
  30. * something like this:
  31. * <pre>
  32. * window.add(child);
  33. * </pre>
  34. * However, using <code>JWindow</code> you would code:
  35. * <pre>
  36. * window.getContentPane().add(child);
  37. * </pre>
  38. * The same is true of setting <code>LayoutManager</code>s, removing components,
  39. * listing children, etc. All these methods should normally be sent to
  40. * the <code>contentPane</code> instead of the <code>JWindow</code> itself.
  41. * The <code>contentPane</code> will always be non-<code>null</code>.
  42. * Attempting to set it to <code>null</code> will cause the <code>JWindow</code>
  43. * to throw an exception. The default <code>contentPane</code> will have a
  44. * <code>BorderLayout</code> manager set on it.
  45. * <p>
  46. * Please see the {@link JRootPane} documentation for a complete description of
  47. * the <code>contentPane</code>, <code>glassPane</code>, and
  48. * <code>layeredPane</code> components.
  49. * <p>
  50. * In a multi-screen environment, you can create a <code>JWindow</code>
  51. * on a different screen device. See {@link java.awt.Window} for more
  52. * information.
  53. * <p>
  54. * For the keyboard keys used by this component in the standard Look and
  55. * Feel (L&F) renditions, see the
  56. * <a href="doc-files/Key-Index.html#JWindow">JWindow</a> key assignments.
  57. * <p>
  58. * <strong>Warning:</strong>
  59. * Serialized objects of this class will not be compatible with
  60. * future Swing releases. The current serialization support is appropriate
  61. * for short term storage or RMI between applications running the same
  62. * version of Swing. A future release of Swing will provide support for
  63. * long term persistence.
  64. *
  65. * @see JRootPane
  66. *
  67. * @beaninfo
  68. * attribute: isContainer true
  69. * attribute: containerDelegate getContentPane
  70. * description: A toplevel window which has no system border or controls.
  71. *
  72. * @version 1.37 02/09/01
  73. * @author David Kloba
  74. */
  75. public class JWindow extends Window implements Accessible, RootPaneContainer
  76. {
  77. /**
  78. * The <code>JRootPane</code> instance that manages the
  79. * <code>contentPane</code>
  80. * and optional <code>menuBar</code> for this frame, as well as the
  81. * <code>glassPane</code>.
  82. *
  83. * @see #getRootPane
  84. * @see #setRootPane
  85. */
  86. protected JRootPane rootPane;
  87. /**
  88. * If true then calls to <code>add</code> and <code>setLayout</code>
  89. * will cause an exception to be thrown.
  90. *
  91. * @see #isRootPaneCheckingEnabled
  92. * @see #setRootPaneCheckingEnabled
  93. */
  94. protected boolean rootPaneCheckingEnabled = false;
  95. /**
  96. * Creates a window with no specified owner.
  97. */
  98. public JWindow() {
  99. this((Frame)null);
  100. }
  101. /**
  102. * Creates a window with the specified <code>GraphicsConfiguration</code>
  103. * of a screen device.
  104. *
  105. * @param gc the <code>GraphicsConfiguration</code> that is used
  106. * to construct the new window with; if gc is <code>null</code>,
  107. * the system default <code>GraphicsConfiguration</code>
  108. * is assumed
  109. *
  110. * @exception IllegalArgumentException if <code>gc</code> is not from
  111. * a screen device.
  112. *
  113. * @since 1.3
  114. */
  115. public JWindow(GraphicsConfiguration gc) {
  116. this((Frame)null, gc);
  117. }
  118. /**
  119. * Creates a window with the specified owner frame.
  120. * If <code>owner</code> is <code>null</code>, the shared owner
  121. * will be used.
  122. *
  123. * @param owner the frame from which the window is displayed
  124. */
  125. public JWindow(Frame owner) {
  126. super(owner == null? SwingUtilities.getSharedOwnerFrame() : owner);
  127. windowInit();
  128. }
  129. /**
  130. * Creates a window with the owner and the specified
  131. * <code>GraphicsConfiguration</code> of a screen device.
  132. * @param owner the window to act as owner
  133. * @param gc the <code>GraphicsConfiguration</code> that is used
  134. * to construct the new <code>Window</code>
  135. * if <code>gc</code> is <code>null</code>, the system
  136. * default <code>GraphicsConfiguration</code> is assumed
  137. * @exception IllegalArgumentException if <code>gc</code> is not from
  138. * a screen device.
  139. * @exception IllegalArgumentException if owner is <code>null</code>
  140. * @since 1.3
  141. */
  142. public JWindow(Window owner) {
  143. super(owner);
  144. windowInit();
  145. }
  146. public JWindow(Window owner, GraphicsConfiguration gc) {
  147. super(owner, gc);
  148. windowInit();
  149. }
  150. /** Called by the constructors to init the <code>JWindow</code> properly. */
  151. protected void windowInit() {
  152. setRootPane(createRootPane());
  153. setRootPaneCheckingEnabled(true);
  154. }
  155. /**
  156. * Called by the constructor methods to create the default
  157. * <code>rootPane</code>.
  158. */
  159. protected JRootPane createRootPane() {
  160. return new JRootPane();
  161. }
  162. /**
  163. * Returns whether calls to <code>add</code> and
  164. * <code>setLayout</code> will cause an exception to be thrown.
  165. *
  166. * @return true if <code>add</code> and <code>setLayout</code>
  167. * are checked
  168. *
  169. * @see #addImpl
  170. * @see #setLayout
  171. * @see #setRootPaneCheckingEnabled
  172. */
  173. protected boolean isRootPaneCheckingEnabled() {
  174. return rootPaneCheckingEnabled;
  175. }
  176. /**
  177. * Determines whether calls to <code>add</code> and
  178. * <code>setLayout</code> will cause an exception to be thrown.
  179. *
  180. * @param enabled a boolean value, true if checking is to be
  181. * enabled, which cause the exceptions to be thrown
  182. *
  183. * @see #addImpl
  184. * @see #setLayout
  185. * @see #isRootPaneCheckingEnabled
  186. * @beaninfo
  187. * hidden: true
  188. * description: Whether the add and setLayout methods throw exceptions when invoked.
  189. */
  190. protected void setRootPaneCheckingEnabled(boolean enabled) {
  191. rootPaneCheckingEnabled = enabled;
  192. }
  193. /**
  194. * Creates a string with a message that can be used for a
  195. * runtime exception. The message will look like:
  196. * <pre>
  197. * "Do not use JWindow.add() use JWindow.getContentPane().add() instead"
  198. * </pre>
  199. *
  200. * @param op a <code>String</code> indicating the attempted operation;
  201. * in the example above, the operation string is "add"
  202. * @return a string containing the message to be used for the exception
  203. */
  204. private Error createRootPaneException(String op) {
  205. String type = getClass().getName();
  206. return new Error(
  207. "Do not use " + type + "." + op + "() use "
  208. + type + ".getContentPane()." + op + "() instead");
  209. }
  210. /**
  211. * By default, children may not be added directly to a this component,
  212. * they must be added to its <code>contentPane</code> instead. For example:
  213. * <pre>
  214. * thisComponent.getContentPane().add(child)
  215. * </pre>
  216. * An attempt to add to directly to this component will cause an
  217. * runtime exception to be thrown. Subclasses can disable this
  218. * behavior.
  219. *
  220. * @param comp the component to be enhanced
  221. * @param constraints the constraints to be enforced on the component
  222. * @param index the index of the component
  223. *
  224. * @see #setRootPaneCheckingEnabled
  225. * @exception Error if called with <code>rootPaneChecking</code> true
  226. */
  227. protected void addImpl(Component comp, Object constraints, int index)
  228. {
  229. if(isRootPaneCheckingEnabled()) {
  230. throw createRootPaneException("add");
  231. }
  232. else {
  233. super.addImpl(comp, constraints, index);
  234. }
  235. }
  236. /**
  237. * Removes the specified component from this container.
  238. * @param comp the component to be removed
  239. * @see #add
  240. */
  241. public void remove(Component comp) {
  242. if (comp == rootPane) {
  243. super.remove(comp);
  244. } else {
  245. // Client mistake, but we need to handle it to avoid a
  246. // common object leak in client applications.
  247. getContentPane().remove(comp);
  248. }
  249. }
  250. /**
  251. * By default the layout of this component may not be set,
  252. * the layout of its contentPane should be set instead.
  253. * For example:
  254. * <pre>
  255. * thisComponent.getContentPane().setLayout(new BorderLayout())
  256. * </pre>
  257. * An attempt to set the layout of this component will cause an
  258. * runtime exception to be thrown. Subclasses can disable this
  259. * behavior.
  260. *
  261. * @param manager the layout manager for the window
  262. * @see #setRootPaneCheckingEnabled
  263. * @exception Error if called with <code>rootPaneChecking</code> true
  264. */
  265. public void setLayout(LayoutManager manager) {
  266. if(isRootPaneCheckingEnabled()) {
  267. throw createRootPaneException("setLayout");
  268. }
  269. else {
  270. super.setLayout(manager);
  271. }
  272. }
  273. /**
  274. * Returns the <code>rootPane</code> object for this window.
  275. * @return the <code>rootPane</code> property for this window
  276. *
  277. * @see #setRootPane
  278. * @see RootPaneContainer#getRootPane
  279. */
  280. public JRootPane getRootPane() {
  281. return rootPane;
  282. }
  283. /**
  284. * Sets the new <code>rootPane</code> object for this window.
  285. * This method is called by the constructor.
  286. *
  287. * @param root the new <code>rootPane</code> property
  288. * @see #getRootPane
  289. *
  290. * @beaninfo
  291. * hidden: true
  292. * description: the RootPane object for this window.
  293. */
  294. protected void setRootPane(JRootPane root) {
  295. if(rootPane != null) {
  296. remove(rootPane);
  297. }
  298. rootPane = root;
  299. if(rootPane != null) {
  300. boolean checkingEnabled = isRootPaneCheckingEnabled();
  301. try {
  302. setRootPaneCheckingEnabled(false);
  303. add(rootPane, BorderLayout.CENTER);
  304. }
  305. finally {
  306. setRootPaneCheckingEnabled(checkingEnabled);
  307. }
  308. }
  309. }
  310. /**
  311. * Returns the <code>Container</code> which is the <code>contentPane</code>
  312. * for this window.
  313. *
  314. * @return the <code>contentPane</code> property
  315. * @see #setContentPane
  316. * @see RootPaneContainer#getContentPane
  317. */
  318. public Container getContentPane() {
  319. return getRootPane().getContentPane();
  320. }
  321. /**
  322. * Sets the <code>contentPane</code> property for this window.
  323. * This method is called by the constructor.
  324. *
  325. * @param contentPane the new <code>contentPane</code>
  326. *
  327. * @exception IllegalComponentStateException (a runtime
  328. * exception) if the content pane parameter is <code>null</code>
  329. * @see #getContentPane
  330. * @see RootPaneContainer#setContentPane
  331. *
  332. * @beaninfo
  333. * hidden: true
  334. * description: The client area of the window where child
  335. * components are normally inserted.
  336. */
  337. public void setContentPane(Container contentPane) {
  338. getRootPane().setContentPane(contentPane);
  339. }
  340. /**
  341. * Returns the <code>layeredPane</code> object for this window.
  342. *
  343. * @return the <code>layeredPane</code> property
  344. * @see #setLayeredPane
  345. * @see RootPaneContainer#getLayeredPane
  346. */
  347. public JLayeredPane getLayeredPane() {
  348. return getRootPane().getLayeredPane();
  349. }
  350. /**
  351. * Sets the <code>layeredPane</code> property.
  352. * This method is called by the constructor.
  353. *
  354. * @param layeredPane the new <code>layeredPane</code> object
  355. *
  356. * @exception IllegalComponentStateException (a runtime
  357. * exception) if the content pane parameter is <code>null</code>
  358. * @see #getLayeredPane
  359. * @see RootPaneContainer#setLayeredPane
  360. *
  361. * @beaninfo
  362. * hidden: true
  363. * description: The pane which holds the various window layers.
  364. */
  365. public void setLayeredPane(JLayeredPane layeredPane) {
  366. getRootPane().setLayeredPane(layeredPane);
  367. }
  368. /**
  369. * Returns the <code>glassPane Component</code> for this window.
  370. *
  371. * @return the <code>glassPane</code> property
  372. * @see #setGlassPane
  373. * @see RootPaneContainer#getGlassPane
  374. */
  375. public Component getGlassPane() {
  376. return getRootPane().getGlassPane();
  377. }
  378. /**
  379. * Sets the <code>glassPane</code> property.
  380. * This method is called by the constructor.
  381. * @param glassPane the <code>glassPane</code> object for this window
  382. *
  383. * @see #getGlassPane
  384. * @see RootPaneContainer#setGlassPane
  385. *
  386. * @beaninfo
  387. * hidden: true
  388. * description: A transparent pane used for menu rendering.
  389. */
  390. public void setGlassPane(Component glassPane) {
  391. getRootPane().setGlassPane(glassPane);
  392. }
  393. /**
  394. * Returns a string representation of this <code>JWindow</code>.
  395. * This method
  396. * is intended to be used only for debugging purposes, and the
  397. * content and format of the returned string may vary between
  398. * implementations. The returned string may be empty but may not
  399. * be <code>null</code>.
  400. *
  401. * @return a string representation of this <code>JWindow</code>
  402. */
  403. protected String paramString() {
  404. String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
  405. "true" : "false");
  406. return super.paramString() +
  407. ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
  408. }
  409. /////////////////
  410. // Accessibility support
  411. ////////////////
  412. /** The accessible context property. */
  413. protected AccessibleContext accessibleContext = null;
  414. /**
  415. * Gets the AccessibleContext associated with this JWindow.
  416. * For JWindows, the AccessibleContext takes the form of an
  417. * AccessibleJWindow.
  418. * A new AccessibleJWindow instance is created if necessary.
  419. *
  420. * @return an AccessibleJWindow that serves as the
  421. * AccessibleContext of this JWindow
  422. */
  423. public AccessibleContext getAccessibleContext() {
  424. if (accessibleContext == null) {
  425. accessibleContext = new AccessibleJWindow();
  426. }
  427. return accessibleContext;
  428. }
  429. /**
  430. * This class implements accessibility support for the
  431. * <code>JWindow</code> class. It provides an implementation of the
  432. * Java Accessibility API appropriate to window user-interface
  433. * elements.
  434. */
  435. protected class AccessibleJWindow extends AccessibleAWTWindow {
  436. // everything is in the new parent, AccessibleAWTWindow
  437. }
  438. }