1. /*
  2. * @(#)JFrame.java 1.104 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. * An extended version of <code>java.awt.Frame</code> that adds support for
  17. * the JFC/Swing component architecture.
  18. * You can find task-oriented documentation about using <code>JFrame</code>
  19. * in <em>The Java Tutorial</em>, in the section
  20. * <a
  21. href="http://java.sun.com/docs/books/tutorial/uiswing/components/frame.html">How to Make Frames</a>.
  22. *
  23. * <p>
  24. * The <code>JFrame</code> class is slightly incompatible with <code>Frame</code>.
  25. * Like all other JFC/Swing top-level containers,
  26. * a <code>JFrame</code> contains a <code>JRootPane</code> as its only child.
  27. * The <b>content pane</b> provided by the root pane should,
  28. * as a rule, contain
  29. * all the non-menu components displayed by the <code>JFrame</code>.
  30. * This is different from the AWT <code>Frame</code> case.
  31. * As a conveniance <code>add</code> and its variants, <code>remove</code> and
  32. * <code>setLayout</code> have been overridden to forward to the
  33. * <code>contentPane</code> as necessary. This means you can write:
  34. * <pre>
  35. * frame.add(child);
  36. * </pre>
  37. * And the child will be added to the contentPane.
  38. * The content pane will
  39. * always be non-null. Attempting to set it to null will cause the JFrame
  40. * to throw an exception. The default content pane will have a BorderLayout
  41. * manager set on it.
  42. * Refer to {@link javax.swing.RootPaneContainer}
  43. * for details on adding, removing and setting the <code>LayoutManager</code>
  44. * of a <code>JFrame</code>.
  45. * <p>
  46. * Unlike a <code>Frame</code>, a <code>JFrame</code> has some notion of how to
  47. * respond when the user attempts to close the window. The default behavior
  48. * is to simply hide the JFrame when the user closes the window. To change the
  49. * default behavior, you invoke the method
  50. * {@link #setDefaultCloseOperation}.
  51. * To make the <code>JFrame</code> behave the same as a <code>Frame</code>
  52. * instance, use
  53. * <code>setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE)</code>.
  54. * <p>
  55. * For more information on content panes
  56. * and other features that root panes provide,
  57. * see <a
  58. href="http://java.sun.com/docs/books/tutorial/uiswing/components/toplevel.html">Using Top-Level Containers</a> in <em>The Java Tutorial</em>.
  59. * <p>
  60. * In a multi-screen environment, you can create a <code>JFrame</code>
  61. * on a different screen device. See {@link java.awt.Frame} for more
  62. * information.
  63. * <p>
  64. * <strong>Warning:</strong>
  65. * Serialized objects of this class will not be compatible with
  66. * future Swing releases. The current serialization support is
  67. * appropriate for short term storage or RMI between applications running
  68. * the same version of Swing. As of 1.4, support for long term storage
  69. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  70. * has been added to the <code>java.beans</code> package.
  71. * Please see {@link java.beans.XMLEncoder}.
  72. *
  73. * @see JRootPane
  74. * @see #setDefaultCloseOperation
  75. * @see java.awt.event.WindowListener#windowClosing
  76. * @see javax.swing.RootPaneContainer
  77. *
  78. * @beaninfo
  79. * attribute: isContainer true
  80. * attribute: containerDelegate getContentPane
  81. * description: A toplevel window which can be minimized to an icon.
  82. *
  83. * @version 1.104 12/19/03
  84. * @author Jeff Dinkins
  85. * @author Georges Saab
  86. * @author David Kloba
  87. */
  88. public class JFrame extends Frame implements WindowConstants, Accessible, RootPaneContainer
  89. {
  90. /**
  91. * The exit application default window close operation. If a window
  92. * has this set as the close operation and is closed in an applet,
  93. * a <code>SecurityException</code> may be thrown.
  94. * It is recommended you only use this in an application.
  95. * <p>
  96. * @since 1.3
  97. */
  98. public static final int EXIT_ON_CLOSE = 3;
  99. /**
  100. * Key into the AppContext, used to check if should provide decorations
  101. * by default.
  102. */
  103. private static final Object defaultLookAndFeelDecoratedKey =
  104. new StringBuffer("JFrame.defaultLookAndFeelDecorated");
  105. private int defaultCloseOperation = HIDE_ON_CLOSE;
  106. /**
  107. * The <code>JRootPane</code> instance that manages the
  108. * <code>contentPane</code>
  109. * and optional <code>menuBar</code> for this frame, as well as the
  110. * <code>glassPane</code>.
  111. *
  112. * @see JRootPane
  113. * @see RootPaneContainer
  114. */
  115. protected JRootPane rootPane;
  116. /**
  117. * If true then calls to <code>add</code> and <code>setLayout</code>
  118. * will be forwarded to the <code>contentPane</code>. This is initially
  119. * false, but is set to true when the <code>JFrame</code> is constructed.
  120. *
  121. * @see #isRootPaneCheckingEnabled
  122. * @see #setRootPaneCheckingEnabled
  123. * @see javax.swing.RootPaneContainer
  124. */
  125. protected boolean rootPaneCheckingEnabled = false;
  126. /**
  127. * Constructs a new frame that is initially invisible.
  128. * <p>
  129. * This constructor sets the component's locale property to the value
  130. * returned by <code>JComponent.getDefaultLocale</code>.
  131. *
  132. * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  133. * returns true.
  134. * @see java.awt.GraphicsEnvironment#isHeadless
  135. * @see Component#setSize
  136. * @see Component#setVisible
  137. * @see JComponent#getDefaultLocale
  138. */
  139. public JFrame() throws HeadlessException {
  140. super();
  141. frameInit();
  142. }
  143. /**
  144. * Creates a <code>Frame</code> in the specified
  145. * <code>GraphicsConfiguration</code> of
  146. * a screen device and a blank title.
  147. * <p>
  148. * This constructor sets the component's locale property to the value
  149. * returned by <code>JComponent.getDefaultLocale</code>.
  150. *
  151. * @param gc the <code>GraphicsConfiguration</code> that is used
  152. * to construct the new <code>Frame</code>
  153. * if <code>gc</code> is <code>null</code>, the system
  154. * default <code>GraphicsConfiguration</code> is assumed
  155. * @exception IllegalArgumentException if <code>gc</code> is not from
  156. * a screen device. This exception is always thrown when
  157. * GraphicsEnvironment.isHeadless() returns true.
  158. * @see java.awt.GraphicsEnvironment#isHeadless
  159. * @see JComponent#getDefaultLocale
  160. * @since 1.3
  161. */
  162. public JFrame(GraphicsConfiguration gc) {
  163. super(gc);
  164. frameInit();
  165. }
  166. /**
  167. * Creates a new, initially invisible <code>Frame</code> with the
  168. * specified title.
  169. * <p>
  170. * This constructor sets the component's locale property to the value
  171. * returned by <code>JComponent.getDefaultLocale</code>.
  172. *
  173. * @param title the title for the frame
  174. * @exception HeadlessException if GraphicsEnvironment.isHeadless()
  175. * returns true.
  176. * @see java.awt.GraphicsEnvironment#isHeadless
  177. * @see Component#setSize
  178. * @see Component#setVisible
  179. * @see JComponent#getDefaultLocale
  180. */
  181. public JFrame(String title) throws HeadlessException {
  182. super(title);
  183. frameInit();
  184. }
  185. /**
  186. * Creates a <code>JFrame</code> with the specified title and the
  187. * specified <code>GraphicsConfiguration</code> of a screen device.
  188. * <p>
  189. * This constructor sets the component's locale property to the value
  190. * returned by <code>JComponent.getDefaultLocale</code>.
  191. *
  192. * @param title the title to be displayed in the
  193. * frame's border. A <code>null</code> value is treated as
  194. * an empty string, "".
  195. * @param gc the <code>GraphicsConfiguration</code> that is used
  196. * to construct the new <code>JFrame</code> with;
  197. * if <code>gc</code> is <code>null</code>, the system
  198. * default <code>GraphicsConfiguration</code> is assumed
  199. * @exception IllegalArgumentException if <code>gc</code> is not from
  200. * a screen device. This exception is always thrown when
  201. * GraphicsEnvironment.isHeadless() returns true.
  202. * @see java.awt.GraphicsEnvironment#isHeadless
  203. * @see JComponent#getDefaultLocale
  204. * @since 1.3
  205. */
  206. public JFrame(String title, GraphicsConfiguration gc) {
  207. super(title, gc);
  208. frameInit();
  209. }
  210. /** Called by the constructors to init the <code>JFrame</code> properly. */
  211. protected void frameInit() {
  212. enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
  213. setLocale( JComponent.getDefaultLocale() );
  214. setRootPane(createRootPane());
  215. setBackground(UIManager.getColor("control"));
  216. setRootPaneCheckingEnabled(true);
  217. if (JFrame.isDefaultLookAndFeelDecorated()) {
  218. boolean supportsWindowDecorations =
  219. UIManager.getLookAndFeel().getSupportsWindowDecorations();
  220. if (supportsWindowDecorations) {
  221. setUndecorated(true);
  222. getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
  223. }
  224. }
  225. sun.awt.SunToolkit.checkAndSetPolicy(this, true);
  226. }
  227. /**
  228. * Called by the constructor methods to create the default
  229. * <code>rootPane</code>.
  230. */
  231. protected JRootPane createRootPane() {
  232. JRootPane rp = new JRootPane();
  233. // NOTE: this uses setOpaque vs LookAndFeel.installProperty as there
  234. // is NO reason for the RootPane not to be opaque. For painting to
  235. // work the contentPane must be opaque, therefor the RootPane can
  236. // also be opaque.
  237. rp.setOpaque(true);
  238. return rp;
  239. }
  240. /**
  241. * Processes window events occurring on this component.
  242. * Hides the window or disposes of it, as specified by the setting
  243. * of the <code>defaultCloseOperation</code> property.
  244. *
  245. * @param e the window event
  246. * @see #setDefaultCloseOperation
  247. * @see java.awt.Window#processWindowEvent
  248. */
  249. protected void processWindowEvent(WindowEvent e) {
  250. super.processWindowEvent(e);
  251. if (e.getID() == WindowEvent.WINDOW_CLOSING) {
  252. switch(defaultCloseOperation) {
  253. case HIDE_ON_CLOSE:
  254. setVisible(false);
  255. break;
  256. case DISPOSE_ON_CLOSE:
  257. setVisible(false);
  258. dispose();
  259. break;
  260. case DO_NOTHING_ON_CLOSE:
  261. default:
  262. break;
  263. case EXIT_ON_CLOSE:
  264. // This needs to match the checkExit call in
  265. // setDefaultCloseOperation
  266. System.exit(0);
  267. break;
  268. }
  269. }
  270. }
  271. // public void setMenuBar(MenuBar menu) {
  272. // throw new IllegalComponentStateException("Please use setJMenuBar() with JFrame.");
  273. // }
  274. /**
  275. * Sets the operation that will happen by default when
  276. * the user initiates a "close" on this frame.
  277. * You must specify one of the following choices:
  278. * <p>
  279. * <ul>
  280. * <li><code>DO_NOTHING_ON_CLOSE</code>
  281. * (defined in <code>WindowConstants</code>):
  282. * Don't do anything; require the
  283. * program to handle the operation in the <code>windowClosing</code>
  284. * method of a registered <code>WindowListener</code> object.
  285. *
  286. * <li><code>HIDE_ON_CLOSE</code>
  287. * (defined in <code>WindowConstants</code>):
  288. * Automatically hide the frame after
  289. * invoking any registered <code>WindowListener</code>
  290. * objects.
  291. *
  292. * <li><code>DISPOSE_ON_CLOSE</code>
  293. * (defined in <code>WindowConstants</code>):
  294. * Automatically hide and dispose the
  295. * frame after invoking any registered <code>WindowListener</code>
  296. * objects.
  297. *
  298. * <li><code>EXIT_ON_CLOSE</code>
  299. * (defined in <code>JFrame</code>):
  300. * Exit the application using the <code>System</code>
  301. * <code>exit</code> method. Use this only in applications.
  302. * </ul>
  303. * <p>
  304. * The value is set to <code>HIDE_ON_CLOSE</code> by default.
  305. * <p>
  306. * <b>Note</b>: When the last displayable window within the
  307. * Java virtual machine (VM) is disposed of, the VM may
  308. * terminate. See <a href="../../java/awt/doc-files/AWTThreadIssues.html">
  309. * AWT Threading Issues</a> for more information.
  310. *
  311. * @param operation the operation which should be performed when the
  312. * user closes the frame
  313. * @exception IllegalArgumentException if defaultCloseOperation value
  314. * isn't one of the above valid values
  315. * @see #addWindowListener
  316. * @see #getDefaultCloseOperation
  317. * @see WindowConstants
  318. * @throws SecurityException
  319. * if <code>EXIT_ON_CLOSE</code> has been specified and the
  320. * <code>SecurityManager</code> will
  321. * not allow the caller to invoke <code>System.exit</code>
  322. * @see java.lang.Runtime#exit(int)
  323. *
  324. * @beaninfo
  325. * preferred: true
  326. * bound: true
  327. * enum: DO_NOTHING_ON_CLOSE WindowConstants.DO_NOTHING_ON_CLOSE
  328. * HIDE_ON_CLOSE WindowConstants.HIDE_ON_CLOSE
  329. * DISPOSE_ON_CLOSE WindowConstants.DISPOSE_ON_CLOSE
  330. * EXIT_ON_CLOSE WindowConstants.EXIT_ON_CLOSE
  331. * description: The frame's default close operation.
  332. */
  333. public void setDefaultCloseOperation(int operation) {
  334. if (operation != DO_NOTHING_ON_CLOSE &&
  335. operation != HIDE_ON_CLOSE &&
  336. operation != DISPOSE_ON_CLOSE &&
  337. operation != EXIT_ON_CLOSE) {
  338. throw new IllegalArgumentException("defaultCloseOperation must be one of: DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE, DISPOSE_ON_CLOSE, or EXIT_ON_CLOSE");
  339. }
  340. if (this.defaultCloseOperation != operation) {
  341. if (operation == EXIT_ON_CLOSE) {
  342. SecurityManager security = System.getSecurityManager();
  343. if (security != null) {
  344. security.checkExit(0);
  345. }
  346. }
  347. int oldValue = this.defaultCloseOperation;
  348. this.defaultCloseOperation = operation;
  349. firePropertyChange("defaultCloseOperation", oldValue, operation);
  350. }
  351. }
  352. /**
  353. * Returns the operation that occurs when the user
  354. * initiates a "close" on this frame.
  355. *
  356. * @return an integer indicating the window-close operation
  357. * @see #setDefaultCloseOperation
  358. */
  359. public int getDefaultCloseOperation() {
  360. return defaultCloseOperation;
  361. }
  362. /**
  363. * Just calls <code>paint(g)</code>. This method was overridden to
  364. * prevent an unnecessary call to clear the background.
  365. *
  366. * @param g the Graphics context in which to paint
  367. */
  368. public void update(Graphics g) {
  369. paint(g);
  370. }
  371. /**
  372. * Sets the menubar for this frame.
  373. * @param menubar the menubar being placed in the frame
  374. *
  375. * @see #getJMenuBar
  376. *
  377. * @beaninfo
  378. * hidden: true
  379. * description: The menubar for accessing pulldown menus from this frame.
  380. */
  381. public void setJMenuBar(JMenuBar menubar) {
  382. getRootPane().setMenuBar(menubar);
  383. }
  384. /**
  385. * Returns the menubar set on this frame.
  386. * @return the menubar for this frame
  387. *
  388. * @see #setJMenuBar
  389. */
  390. public JMenuBar getJMenuBar() {
  391. return getRootPane().getMenuBar();
  392. }
  393. /**
  394. * Returns whether calls to <code>add</code> and
  395. * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
  396. *
  397. * @return true if <code>add</code> and <code>setLayout</code>
  398. * are fowarded; false otherwise
  399. *
  400. * @see #addImpl
  401. * @see #setLayout
  402. * @see #setRootPaneCheckingEnabled
  403. * @see javax.swing.RootPaneContainer
  404. */
  405. protected boolean isRootPaneCheckingEnabled() {
  406. return rootPaneCheckingEnabled;
  407. }
  408. /**
  409. * Sets whether calls to <code>add</code> and
  410. * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
  411. *
  412. * @param enabled true if <code>add</code> and <code>setLayout</code>
  413. * are forwarded, false if they should operate directly on the
  414. * <code>JFrame</code>.
  415. *
  416. * @see #addImpl
  417. * @see #setLayout
  418. * @see #isRootPaneCheckingEnabled
  419. * @see javax.swing.RootPaneContainer
  420. * @beaninfo
  421. * hidden: true
  422. * description: Whether the add and setLayout methods are forwarded
  423. */
  424. protected void setRootPaneCheckingEnabled(boolean enabled) {
  425. rootPaneCheckingEnabled = enabled;
  426. }
  427. /**
  428. * Adds the specified child <code>Component</code>.
  429. * This method is overridden to conditionally forwad calls to the
  430. * <code>contentPane</code>.
  431. * By default, children are added to the <code>contentPane</code> instead
  432. * of the frame, refer to {@link javax.swing.RootPaneContainer} for
  433. * details.
  434. *
  435. * @param comp the component to be enhanced
  436. * @param constraints the constraints to be respected
  437. * @param index the index
  438. * @exception IllegalArgumentException if <code>index</code> is invalid
  439. * @exception IllegalArgumentException if adding the container's parent
  440. * to itself
  441. * @exception IllegalArgumentException if adding a window to a container
  442. *
  443. * @see #setRootPaneCheckingEnabled
  444. * @see javax.swing.RootPaneContainer
  445. */
  446. protected void addImpl(Component comp, Object constraints, int index)
  447. {
  448. if(isRootPaneCheckingEnabled()) {
  449. getContentPane().add(comp, constraints, index);
  450. }
  451. else {
  452. super.addImpl(comp, constraints, index);
  453. }
  454. }
  455. /**
  456. * Removes the specified component from the container. If
  457. * <code>comp</code> is not the <code>rootPane</code>, this will forward
  458. * the call to the <code>contentPane</code>. This will do nothing if
  459. * <code>comp</code> is not a child of the <code>JFrame</code> or
  460. * <code>contentPane</code>.
  461. *
  462. * @param comp the component to be removed
  463. * @throws NullPointerException if <code>comp</code> is null
  464. * @see #add
  465. * @see javax.swing.RootPaneContainer
  466. */
  467. public void remove(Component comp) {
  468. if (comp == rootPane) {
  469. super.remove(comp);
  470. } else {
  471. getContentPane().remove(comp);
  472. }
  473. }
  474. /**
  475. * Sets the <code>LayoutManager</code>.
  476. * Overridden to conditionally forward the call to the
  477. * <code>contentPane</code>.
  478. * Refer to {@link javax.swing.RootPaneContainer} for
  479. * more information.
  480. *
  481. * @param manager the <code>LayoutManager</code>
  482. * @see #setRootPaneCheckingEnabled
  483. * @see javax.swing.RootPaneContainer
  484. */
  485. public void setLayout(LayoutManager manager) {
  486. if(isRootPaneCheckingEnabled()) {
  487. getContentPane().setLayout(manager);
  488. }
  489. else {
  490. super.setLayout(manager);
  491. }
  492. }
  493. /**
  494. * Returns the <code>rootPane</code> object for this frame.
  495. * @return the <code>rootPane</code> property
  496. *
  497. * @see #setRootPane
  498. * @see RootPaneContainer#getRootPane
  499. */
  500. public JRootPane getRootPane() {
  501. return rootPane;
  502. }
  503. /**
  504. * Sets the <code>rootPane</code> property.
  505. * This method is called by the constructor.
  506. * @param root the <code>rootPane</code> object for this frame
  507. *
  508. * @see #getRootPane
  509. *
  510. * @beaninfo
  511. * hidden: true
  512. * description: the RootPane object for this frame.
  513. */
  514. protected void setRootPane(JRootPane root)
  515. {
  516. if(rootPane != null) {
  517. remove(rootPane);
  518. }
  519. rootPane = root;
  520. if(rootPane != null) {
  521. boolean checkingEnabled = isRootPaneCheckingEnabled();
  522. try {
  523. setRootPaneCheckingEnabled(false);
  524. add(rootPane, BorderLayout.CENTER);
  525. }
  526. finally {
  527. setRootPaneCheckingEnabled(checkingEnabled);
  528. }
  529. }
  530. }
  531. public void setIconImage(Image image) {
  532. Image oldImage = getIconImage();
  533. super.setIconImage(image);
  534. firePropertyChange("iconImage", oldImage, image);
  535. }
  536. /**
  537. * Returns the <code>contentPane</code> object for this frame.
  538. * @return the <code>contentPane</code> property
  539. *
  540. * @see #setContentPane
  541. * @see RootPaneContainer#getContentPane
  542. */
  543. public Container getContentPane() {
  544. return getRootPane().getContentPane();
  545. }
  546. /**
  547. * Sets the <code>contentPane</code> property.
  548. * This method is called by the constructor.
  549. * <p>
  550. * Swing's painting architecture requires an opaque <code>JComponent</code>
  551. * in the containment hiearchy. This is typically provided by the
  552. * content pane. If you replace the content pane it is recommended you
  553. * replace it with an opaque <code>JComponent</code>.
  554. *
  555. * @param contentPane the <code>contentPane</code> object for this frame
  556. *
  557. * @exception java.awt.IllegalComponentStateException (a runtime
  558. * exception) if the content pane parameter is <code>null</code>
  559. * @see #getContentPane
  560. * @see RootPaneContainer#setContentPane
  561. * @see JRootPane
  562. *
  563. * @beaninfo
  564. * hidden: true
  565. * description: The client area of the frame where child
  566. * components are normally inserted.
  567. */
  568. public void setContentPane(Container contentPane) {
  569. getRootPane().setContentPane(contentPane);
  570. }
  571. /**
  572. * Returns the <code>layeredPane</code> object for this frame.
  573. * @return the <code>layeredPane</code> property
  574. *
  575. * @see #setLayeredPane
  576. * @see RootPaneContainer#getLayeredPane
  577. */
  578. public JLayeredPane getLayeredPane() {
  579. return getRootPane().getLayeredPane();
  580. }
  581. /**
  582. * Sets the <code>layeredPane</code> property.
  583. * This method is called by the constructor.
  584. * @param layeredPane the <code>layeredPane</code> object for this frame
  585. *
  586. * @exception java.awt.IllegalComponentStateException (a runtime
  587. * exception) if the layered pane parameter is <code>null</code>
  588. * @see #getLayeredPane
  589. * @see RootPaneContainer#setLayeredPane
  590. *
  591. * @beaninfo
  592. * hidden: true
  593. * description: The pane that holds the various frame layers.
  594. */
  595. public void setLayeredPane(JLayeredPane layeredPane) {
  596. getRootPane().setLayeredPane(layeredPane);
  597. }
  598. /**
  599. * Returns the <code>glassPane</code> object for this frame.
  600. * @return the <code>glassPane</code> property
  601. *
  602. * @see #setGlassPane
  603. * @see RootPaneContainer#getGlassPane
  604. */
  605. public Component getGlassPane() {
  606. return getRootPane().getGlassPane();
  607. }
  608. /**
  609. * Sets the <code>glassPane</code> property.
  610. * This method is called by the constructor.
  611. * @param glassPane the <code>glassPane</code> object for this frame
  612. *
  613. * @see #getGlassPane
  614. * @see RootPaneContainer#setGlassPane
  615. *
  616. * @beaninfo
  617. * hidden: true
  618. * description: A transparent pane used for menu rendering.
  619. */
  620. public void setGlassPane(Component glassPane) {
  621. getRootPane().setGlassPane(glassPane);
  622. }
  623. /**
  624. * Provides a hint as to whether or not newly created <code>JFrame</code>s
  625. * should have their Window decorations (such as borders, widgets to
  626. * close the window, title...) provided by the current look
  627. * and feel. If <code>defaultLookAndFeelDecorated</code> is true,
  628. * the current <code>LookAndFeel</code> supports providing window
  629. * decorations, and the current window manager supports undecorated
  630. * windows, then newly created <code>JFrame</code>s will have their
  631. * Window decorations provided by the current <code>LookAndFeel</code>.
  632. * Otherwise, newly created <code>JFrame</code>s will have their
  633. * Window decorations provided by the current window manager.
  634. * <p>
  635. * You can get the same effect on a single JFrame by doing the following:
  636. * <pre>
  637. * JFrame frame = new JFrame();
  638. * frame.setUndecorated(true);
  639. * frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
  640. * </pre>
  641. *
  642. * @param defaultLookAndFeelDecorated A hint as to whether or not current
  643. * look and feel should provide window decorations
  644. * @see javax.swing.LookAndFeel#getSupportsWindowDecorations
  645. * @since 1.4
  646. */
  647. public static void setDefaultLookAndFeelDecorated(boolean defaultLookAndFeelDecorated) {
  648. if (defaultLookAndFeelDecorated) {
  649. SwingUtilities.appContextPut(defaultLookAndFeelDecoratedKey, Boolean.TRUE);
  650. } else {
  651. SwingUtilities.appContextPut(defaultLookAndFeelDecoratedKey, Boolean.FALSE);
  652. }
  653. }
  654. /**
  655. * Returns true if newly created <code>JFrame</code>s should have their
  656. * Window decorations provided by the current look and feel. This is only
  657. * a hint, as certain look and feels may not support this feature.
  658. *
  659. * @return true if look and feel should provide Window decorations.
  660. * @since 1.4
  661. */
  662. public static boolean isDefaultLookAndFeelDecorated() {
  663. Boolean defaultLookAndFeelDecorated =
  664. (Boolean) SwingUtilities.appContextGet(defaultLookAndFeelDecoratedKey);
  665. if (defaultLookAndFeelDecorated == null) {
  666. defaultLookAndFeelDecorated = Boolean.FALSE;
  667. }
  668. return defaultLookAndFeelDecorated.booleanValue();
  669. }
  670. /**
  671. * Returns a string representation of this <code>JFrame</code>.
  672. * This method
  673. * is intended to be used only for debugging purposes, and the
  674. * content and format of the returned string may vary between
  675. * implementations. The returned string may be empty but may not
  676. * be <code>null</code>.
  677. *
  678. * @return a string representation of this <code>JFrame</code>
  679. */
  680. protected String paramString() {
  681. String defaultCloseOperationString;
  682. if (defaultCloseOperation == HIDE_ON_CLOSE) {
  683. defaultCloseOperationString = "HIDE_ON_CLOSE";
  684. } else if (defaultCloseOperation == DISPOSE_ON_CLOSE) {
  685. defaultCloseOperationString = "DISPOSE_ON_CLOSE";
  686. } else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) {
  687. defaultCloseOperationString = "DO_NOTHING_ON_CLOSE";
  688. } else if (defaultCloseOperation == 3) {
  689. defaultCloseOperationString = "EXIT_ON_CLOSE";
  690. } else defaultCloseOperationString = "";
  691. String rootPaneString = (rootPane != null ?
  692. rootPane.toString() : "");
  693. String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
  694. "true" : "false");
  695. return super.paramString() +
  696. ",defaultCloseOperation=" + defaultCloseOperationString +
  697. ",rootPane=" + rootPaneString +
  698. ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
  699. }
  700. /////////////////
  701. // Accessibility support
  702. ////////////////
  703. /** The accessible context property. */
  704. protected AccessibleContext accessibleContext = null;
  705. /**
  706. * Gets the AccessibleContext associated with this JFrame.
  707. * For JFrames, the AccessibleContext takes the form of an
  708. * AccessibleJFrame.
  709. * A new AccessibleJFrame instance is created if necessary.
  710. *
  711. * @return an AccessibleJFrame that serves as the
  712. * AccessibleContext of this JFrame
  713. */
  714. public AccessibleContext getAccessibleContext() {
  715. if (accessibleContext == null) {
  716. accessibleContext = new AccessibleJFrame();
  717. }
  718. return accessibleContext;
  719. }
  720. /**
  721. * This class implements accessibility support for the
  722. * <code>JFrame</code> class. It provides an implementation of the
  723. * Java Accessibility API appropriate to frame user-interface
  724. * elements.
  725. */
  726. protected class AccessibleJFrame extends AccessibleAWTFrame {
  727. // AccessibleContext methods
  728. /**
  729. * Get the accessible name of this object.
  730. *
  731. * @return the localized name of the object -- can be null if this
  732. * object does not have a name
  733. */
  734. public String getAccessibleName() {
  735. if (accessibleName != null) {
  736. return accessibleName;
  737. } else {
  738. if (getTitle() == null) {
  739. return super.getAccessibleName();
  740. } else {
  741. return getTitle();
  742. }
  743. }
  744. }
  745. /**
  746. * Get the state of this object.
  747. *
  748. * @return an instance of AccessibleStateSet containing the current
  749. * state set of the object
  750. * @see AccessibleState
  751. */
  752. public AccessibleStateSet getAccessibleStateSet() {
  753. AccessibleStateSet states = super.getAccessibleStateSet();
  754. if (isResizable()) {
  755. states.add(AccessibleState.RESIZABLE);
  756. }
  757. if (getFocusOwner() != null) {
  758. states.add(AccessibleState.ACTIVE);
  759. }
  760. // FIXME: [[[WDW - should also return ICONIFIED and ICONIFIABLE
  761. // if we can ever figure these out]]]
  762. return states;
  763. }
  764. } // inner class AccessibleJFrame
  765. }