1. /*
  2. * @(#)Frame.java 1.139 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt;
  8. import java.awt.peer.FramePeer;
  9. import java.awt.event.*;
  10. import java.util.Vector;
  11. import java.io.Serializable;
  12. import java.io.ObjectOutputStream;
  13. import java.io.ObjectInputStream;
  14. import java.io.IOException;
  15. import sun.awt.AppContext;
  16. import java.lang.ref.WeakReference;
  17. import javax.accessibility.*;
  18. /**
  19. * A <code>Frame</code> is a top-level window with a title and a border.
  20. * <p>
  21. * The size of the frame includes any area designated for the
  22. * border. The dimensions of the border area may be obtained
  23. * using the <code>getInsets</code> method, however, since
  24. * these dimensions are platform-dependent, a valid insets
  25. * value cannot be obtained until the frame is made displayable
  26. * by either calling <code>pack</code> or <code>show</code>.
  27. * Since the border area is included in the overall size of the
  28. * frame, the border effectively obscures a portion of the frame,
  29. * constraining the area available for rendering and/or displaying
  30. * subcomponents to the rectangle which has an upper-left corner
  31. * location of <code>(insets.left, insets.top)</code>, and has a size of
  32. * <code>width - (insets.left + insets.right)</code> by
  33. * <code>height - (insets.top + insets.bottom)</code>.
  34. * <p>
  35. * The default layout for a frame is <code>BorderLayout</code>.
  36. * <p>
  37. * A frame may have its native decorations (i.e. <code>Frame</code>
  38. * and <code>Titlebar</code>) turned off
  39. * with <code>setUndecorated</code>. This can only be done while the frame
  40. * is not {@link Component#isDisplayable() displayable}.
  41. * <p>
  42. * In a multi-screen environment, you can create a <code>Frame</code>
  43. * on a different screen device by constructing the <code>Frame</code>
  44. * with {@link #Frame(GraphicsConfiguration)} or
  45. * {@link #Frame(String title, GraphicsConfiguration)}. The
  46. * <code>GraphicsConfiguration</code> object is one of the
  47. * <code>GraphicsConfiguration</code> objects of the target screen
  48. * device.
  49. * <p>
  50. * In a virtual device multi-screen environment in which the desktop
  51. * area could span multiple physical screen devices, the bounds of all
  52. * configurations are relative to the virtual-coordinate system. The
  53. * origin of the virtual-coordinate system is at the upper left-hand
  54. * corner of the primary physical screen. Depending on the location
  55. * of the primary screen in the virtual device, negative coordinates
  56. * are possible, as shown in the following figure.
  57. * <p>
  58. * <img src="doc-files/MultiScreen.gif"
  59. * alt="Diagram of virtual device encompassing three physical screens and one primary physical screen. The primary physical screen
  60. * shows (0,0) coords while a different physical screen shows (-80,-100) coords."
  61. * ALIGN=center HSPACE=10 VSPACE=7>
  62. * <p>
  63. * In such an environment, when calling <code>setLocation</code>,
  64. * you must pass a virtual coordinate to this method. Similarly,
  65. * calling <code>getLocationOnScreen</code> on a <code>Frame</code>
  66. * returns virtual device coordinates. Call the <code>getBounds</code>
  67. * method of a <code>GraphicsConfiguration</code> to find its origin in
  68. * the virtual coordinate system.
  69. * <p>
  70. * The following code sets the
  71. * location of the <code>Frame</code> at (10, 10) relative
  72. * to the origin of the physical screen of the corresponding
  73. * <code>GraphicsConfiguration</code>. If the bounds of the
  74. * <code>GraphicsConfiguration</code> is not taken into account, the
  75. * <code>Frame</code> location would be set at (10, 10) relative to the
  76. * virtual-coordinate system and would appear on the primary physical
  77. * screen, which might be different from the physical screen of the
  78. * specified <code>GraphicsConfiguration</code>.
  79. *
  80. * <pre>
  81. * Frame f = new Frame(GraphicsConfiguration gc);
  82. * Rectangle bounds = gc.getBounds();
  83. * f.setLocation(10 + bounds.x, 10 + bounds.y);
  84. * </pre>
  85. *
  86. * <p>
  87. * Frames are capable of generating the following types of
  88. * <code>WindowEvent</code>s:
  89. * <ul>
  90. * <li><code>WINDOW_OPENED</code>
  91. * <li><code>WINDOW_CLOSING</code>
  92. * <li><code>WINDOW_CLOSED</code>
  93. * <li><code>WINDOW_ICONIFIED</code>
  94. * <li><code>WINDOW_DEICONIFIED</code>
  95. * <li><code>WINDOW_ACTIVATED</code>
  96. * <li><code>WINDOW_DEACTIVATED</code>
  97. * <li><code>WINDOW_GAINED_FOCUS</code>
  98. * <li><code>WINDOW_LOST_FOCUS</code>
  99. * <li><code>WINDOW_STATE_CHANGED</code>
  100. * </ul>
  101. *
  102. * @version 1.139, 01/23/03
  103. * @author Sami Shaio
  104. * @see WindowEvent
  105. * @see Window#addWindowListener
  106. * @since JDK1.0
  107. */
  108. public class Frame extends Window implements MenuContainer {
  109. /* Note: These are being obsoleted; programs should use the Cursor class
  110. * variables going forward. See Cursor and Component.setCursor.
  111. */
  112. /**
  113. * @deprecated replaced by <code>Cursor.DEFAULT_CURSOR</code>.
  114. */
  115. public static final int DEFAULT_CURSOR = Cursor.DEFAULT_CURSOR;
  116. /**
  117. * @deprecated replaced by <code>Cursor.CROSSHAIR_CURSOR</code>.
  118. */
  119. public static final int CROSSHAIR_CURSOR = Cursor.CROSSHAIR_CURSOR;
  120. /**
  121. * @deprecated replaced by <code>Cursor.TEXT_CURSOR</code>.
  122. */
  123. public static final int TEXT_CURSOR = Cursor.TEXT_CURSOR;
  124. /**
  125. * @deprecated replaced by <code>Cursor.WAIT_CURSOR</code>.
  126. */
  127. public static final int WAIT_CURSOR = Cursor.WAIT_CURSOR;
  128. /**
  129. * @deprecated replaced by <code>Cursor.SW_RESIZE_CURSOR</code>.
  130. */
  131. public static final int SW_RESIZE_CURSOR = Cursor.SW_RESIZE_CURSOR;
  132. /**
  133. * @deprecated replaced by <code>Cursor.SE_RESIZE_CURSOR</code>.
  134. */
  135. public static final int SE_RESIZE_CURSOR = Cursor.SE_RESIZE_CURSOR;
  136. /**
  137. * @deprecated replaced by <code>Cursor.NW_RESIZE_CURSOR</code>.
  138. */
  139. public static final int NW_RESIZE_CURSOR = Cursor.NW_RESIZE_CURSOR;
  140. /**
  141. * @deprecated replaced by <code>Cursor.NE_RESIZE_CURSOR</code>.
  142. */
  143. public static final int NE_RESIZE_CURSOR = Cursor.NE_RESIZE_CURSOR;
  144. /**
  145. * @deprecated replaced by <code>Cursor.N_RESIZE_CURSOR</code>.
  146. */
  147. public static final int N_RESIZE_CURSOR = Cursor.N_RESIZE_CURSOR;
  148. /**
  149. * @deprecated replaced by <code>Cursor.S_RESIZE_CURSOR</code>.
  150. */
  151. public static final int S_RESIZE_CURSOR = Cursor.S_RESIZE_CURSOR;
  152. /**
  153. * @deprecated replaced by <code>Cursor.W_RESIZE_CURSOR</code>.
  154. */
  155. public static final int W_RESIZE_CURSOR = Cursor.W_RESIZE_CURSOR;
  156. /**
  157. * @deprecated replaced by <code>Cursor.E_RESIZE_CURSOR</code>.
  158. */
  159. public static final int E_RESIZE_CURSOR = Cursor.E_RESIZE_CURSOR;
  160. /**
  161. * @deprecated replaced by <code>Cursor.HAND_CURSOR</code>.
  162. */
  163. public static final int HAND_CURSOR = Cursor.HAND_CURSOR;
  164. /**
  165. * @deprecated replaced by <code>Cursor.MOVE_CURSOR</code>.
  166. */
  167. public static final int MOVE_CURSOR = Cursor.MOVE_CURSOR;
  168. /**
  169. * Frame is in the "normal" state. This symbolic constant names a
  170. * frame state with all state bits cleared.
  171. * @see #setExtendedState(int)
  172. * @see #getExtendedState
  173. */
  174. public static final int NORMAL = 0;
  175. /**
  176. * This state bit indicates that frame is iconified.
  177. * @see #setExtendedState(int)
  178. * @see #getExtendedState
  179. */
  180. public static final int ICONIFIED = 1;
  181. /**
  182. * This state bit indicates that frame is maximized in the
  183. * horizontal direction.
  184. * @see #setExtendedState(int)
  185. * @see #getExtendedState
  186. * @since 1.4
  187. */
  188. public static final int MAXIMIZED_HORIZ = 2;
  189. /**
  190. * This state bit indicates that frame is maximized in the
  191. * vertical direction.
  192. * @see #setExtendedState(int)
  193. * @see #getExtendedState
  194. * @since 1.4
  195. */
  196. public static final int MAXIMIZED_VERT = 4;
  197. /**
  198. * This state bit mask indicates that frame is fully maximized
  199. * (that is both horizontally and vertically). It is just a
  200. * convenience alias for
  201. * <code>MAXIMIZED_VERT | MAXIMIZED_HORIZ</code>.
  202. *
  203. * <p>Note that the correct test for frame being fully maximized is
  204. * <pre>
  205. * (state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH
  206. * </pre>
  207. *
  208. * <p>To test is frame is maximized in <em>some</em> direction use
  209. * <pre>
  210. * (state & Frame.MAXIMIZED_BOTH) != 0
  211. * </pre>
  212. *
  213. * @see #setExtendedState(int)
  214. * @see #getExtendedState
  215. * @since 1.4
  216. */
  217. public static final int MAXIMIZED_BOTH = MAXIMIZED_VERT | MAXIMIZED_HORIZ;
  218. /**
  219. * Maximized bounds for this frame.
  220. * @see #setMaximizedBounds(Rectangle)
  221. * @see #getMaximizedBounds
  222. * @serial
  223. * @since 1.4
  224. */
  225. Rectangle maximizedBounds;
  226. /**
  227. * This is the title of the frame. It can be changed
  228. * at any time. <code>title</code> can be null and if
  229. * this is the case the <code>title</code> = "".
  230. *
  231. * @serial
  232. * @see #getTitle
  233. * @see #setTitle(String)
  234. */
  235. String title = "Untitled";
  236. /**
  237. * <code>icon</code> is the graphical way we can
  238. * represent the frame.
  239. * <code>icon</code> can be null, but obviously if
  240. * you try to set the icon image <code>icon</code>
  241. * cannot be null.
  242. *
  243. * @serial
  244. * @see #getIconImage
  245. * @see #setIconImage(Image)
  246. */
  247. transient Image icon;
  248. /**
  249. * The frames menubar. If <code>menuBar</code> = null
  250. * the frame will not have a menubar.
  251. *
  252. * @serial
  253. * @see #getMenuBar
  254. * @see #setMenuBar(MenuBar)
  255. */
  256. MenuBar menuBar;
  257. /**
  258. * This field indicates whether the frame is resizable.
  259. * This property can be changed at any time.
  260. * <code>resizable</code> will be true if the frame is
  261. * resizable, otherwise it will be false.
  262. *
  263. * @serial
  264. * @see #isResizable()
  265. */
  266. boolean resizable = true;
  267. /**
  268. * This field indicates whether the frame is undecorated.
  269. * This property can only be changed while the frame is not displayable.
  270. * <code>undecorated</code> will be true if the frame is
  271. * undecorated, otherwise it will be false.
  272. *
  273. * @serial
  274. * @see #setUndecorated(boolean)
  275. * @see #isUndecorated()
  276. * @see Component#isDisplayable()
  277. * @since 1.4
  278. */
  279. boolean undecorated = false;
  280. /**
  281. * <code>mbManagement</code> is only used by the Motif implementation.
  282. *
  283. * @serial
  284. */
  285. boolean mbManagement = false; /* used only by the Motif impl. */
  286. // XXX: uwe: abuse old field for now
  287. // will need to take care of serialization
  288. private int state = NORMAL;
  289. /*
  290. * The Windows owned by the Frame.
  291. * Note: in 1.2 this has been superceded by Window.ownedWindowList
  292. *
  293. * @serial
  294. * @see java.awt.Window#ownedWindowList
  295. */
  296. Vector ownedWindows;
  297. /*
  298. * We insert a weak reference into the Vector of all Frames
  299. * instead of 'this' so that garbage collection can still take
  300. * place correctly.
  301. */
  302. transient private WeakReference weakThis;
  303. private static final String base = "frame";
  304. private static int nameCounter = 0;
  305. /*
  306. * JDK 1.1 serialVersionUID
  307. */
  308. private static final long serialVersionUID = 2673458971256075116L;
  309. static {
  310. /* ensure that the necessary native libraries are loaded */
  311. Toolkit.loadLibraries();
  312. if (!GraphicsEnvironment.isHeadless()) {
  313. initIDs();
  314. }
  315. }
  316. /**
  317. * Constructs a new instance of <code>Frame</code> that is
  318. * initially invisible. The title of the <code>Frame</code>
  319. * is empty.
  320. * @exception HeadlessException when GraphicsEnvironment.isHeadless()
  321. * returns true
  322. * @see java.awt.GraphicsEnvironment#isHeadless()
  323. * @see Component#setSize
  324. * @see Component#setVisible(boolean)
  325. */
  326. public Frame() throws HeadlessException {
  327. this("");
  328. }
  329. /**
  330. * Create a <code>Frame</code> with the specified
  331. * <code>GraphicsConfiguration</code> of
  332. * a screen device.
  333. * @param gc the <code>GraphicsConfiguration</code>
  334. * of the target screen device. If <code>gc</code>
  335. * is <code>null</code>, the system default
  336. * <code>GraphicsConfiguration</code> is assumed.
  337. * @exception IllegalArgumentException if
  338. * <code>gc</code> is not from a screen device.
  339. * This exception is always thrown
  340. * when GraphicsEnvironment.isHeadless() returns true
  341. * @see java.awt.GraphicsEnvironment#isHeadless()
  342. * @since 1.3
  343. */
  344. public Frame(GraphicsConfiguration gc) {
  345. this("", gc);
  346. }
  347. /**
  348. * Constructs a new, initially invisible <code>Frame</code> object
  349. * with the specified title.
  350. * @param title the title to be displayed in the frame's border.
  351. * A <code>null</code> value
  352. * is treated as an empty string, "".
  353. * @exception HeadlessException when GraphicsEnvironment.isHeadless()
  354. * returns true
  355. * @see java.awt.GraphicsEnvironment#isHeadless()
  356. * @see java.awt.Component#setSize
  357. * @see java.awt.Component#setVisible(boolean)
  358. * @see java.awt.GraphicsConfiguration#getBounds
  359. */
  360. public Frame(String title) throws HeadlessException {
  361. init(title, null);
  362. }
  363. /**
  364. * Constructs a new, initially invisible <code>Frame</code> object
  365. * with the specified title and a
  366. * <code>GraphicsConfiguration</code>.
  367. * @param title the title to be displayed in the frame's border.
  368. * A <code>null</code> value
  369. * is treated as an empty string, "".
  370. * @param gc the <code>GraphicsConfiguration</code>
  371. * of the target screen device. If <code>gc</code> is
  372. * <code>null</code>, the system default
  373. * <code>GraphicsConfiguration</code> is assumed.
  374. * @exception IllegalArgumentException if <code>gc</code>
  375. * is not from a screen device.
  376. * This exception is always thrown
  377. * when GraphicsEnvironment.isHeadless() returns true
  378. * @see java.awt.GraphicsEnvironment#isHeadless()
  379. * @see java.awt.Component#setSize
  380. * @see java.awt.Component#setVisible(boolean)
  381. * @see java.awt.GraphicsConfiguration#getBounds
  382. */
  383. public Frame(String title, GraphicsConfiguration gc) {
  384. super(gc);
  385. init(title, gc);
  386. }
  387. private void init(String title, GraphicsConfiguration gc) {
  388. this.title = title;
  389. weakThis = new WeakReference(this);
  390. addToFrameList();
  391. setFocusTraversalPolicy(KeyboardFocusManager.
  392. getCurrentKeyboardFocusManager().
  393. getDefaultFocusTraversalPolicy()
  394. );
  395. }
  396. /**
  397. * We have to remove the (hard) reference to weakThis in the
  398. * Vector, otherwise the WeakReference instance will never get
  399. * garbage collected.
  400. */
  401. protected void finalize() throws Throwable {
  402. removeFromFrameList();
  403. super.finalize();
  404. }
  405. /**
  406. * Construct a name for this component. Called by getName() when the
  407. * name is null.
  408. */
  409. String constructComponentName() {
  410. synchronized (getClass()) {
  411. return base + nameCounter++;
  412. }
  413. }
  414. /**
  415. * Makes this Frame displayable by connecting it to
  416. * a native screen resource. Making a frame displayable will
  417. * cause any of its children to be made displayable.
  418. * This method is called internally by the toolkit and should
  419. * not be called directly by programs.
  420. * @see Component#isDisplayable
  421. * @see #removeNotify
  422. */
  423. public void addNotify() {
  424. synchronized (getTreeLock()) {
  425. if (peer == null) {
  426. peer = getToolkit().createFrame(this);
  427. }
  428. FramePeer p = (FramePeer)peer;
  429. MenuBar menuBar = this.menuBar;
  430. if (menuBar != null) {
  431. mbManagement = true;
  432. menuBar.addNotify();
  433. p.setMenuBar(menuBar);
  434. }
  435. p.setMaximizedBounds(maximizedBounds);
  436. super.addNotify();
  437. }
  438. }
  439. /**
  440. * Gets the title of the frame. The title is displayed in the
  441. * frame's border.
  442. * @return the title of this frame, or an empty string ("")
  443. * if this frame doesn't have a title.
  444. * @see #setTitle(String)
  445. */
  446. public String getTitle() {
  447. return title;
  448. }
  449. /**
  450. * Sets the title for this frame to the specified string.
  451. * @param title the title to be displayed in the frame's border.
  452. * A <code>null</code> value
  453. * is treated as an empty string, "".
  454. * @see #getTitle
  455. */
  456. public void setTitle(String title) {
  457. String oldTitle = this.title;
  458. if (title == null) {
  459. title = "";
  460. }
  461. synchronized(this) {
  462. this.title = title;
  463. FramePeer peer = (FramePeer)this.peer;
  464. if (peer != null) {
  465. peer.setTitle(title);
  466. }
  467. }
  468. firePropertyChange("title", oldTitle, title);
  469. }
  470. /**
  471. * Gets the image to be displayed in the minimized icon
  472. * for this frame.
  473. * @return the icon image for this frame, or <code>null</code>
  474. * if this frame doesn't have an icon image.
  475. * @see #setIconImage(Image)
  476. */
  477. public Image getIconImage() {
  478. return icon;
  479. }
  480. /**
  481. * Sets the image to be displayed in the minimized icon for this frame.
  482. * Not all platforms support the concept of minimizing a window.
  483. * @param image the icon image to be displayed.
  484. * If this parameter is <code>null</code> then the
  485. * icon image is set to the default image, which may vary
  486. * with platform.
  487. * @see #getIconImage
  488. */
  489. public synchronized void setIconImage(Image image) {
  490. this.icon = image;
  491. FramePeer peer = (FramePeer)this.peer;
  492. if (peer != null) {
  493. peer.setIconImage(image);
  494. }
  495. }
  496. /**
  497. * Gets the menu bar for this frame.
  498. * @return the menu bar for this frame, or <code>null</code>
  499. * if this frame doesn't have a menu bar.
  500. * @see #setMenuBar(MenuBar)
  501. */
  502. public MenuBar getMenuBar() {
  503. return menuBar;
  504. }
  505. /**
  506. * Sets the menu bar for this frame to the specified menu bar.
  507. * @param mb the menu bar being set.
  508. * If this parameter is <code>null</code> then any
  509. * existing menu bar on this frame is removed.
  510. * @see #getMenuBar
  511. */
  512. public void setMenuBar(MenuBar mb) {
  513. synchronized (getTreeLock()) {
  514. if (menuBar == mb) {
  515. return;
  516. }
  517. if ((mb != null) && (mb.parent != null)) {
  518. mb.parent.remove(mb);
  519. }
  520. if (menuBar != null) {
  521. remove(menuBar);
  522. }
  523. menuBar = mb;
  524. if (menuBar != null) {
  525. menuBar.parent = this;
  526. FramePeer peer = (FramePeer)this.peer;
  527. if (peer != null) {
  528. mbManagement = true;
  529. menuBar.addNotify();
  530. if (valid) {
  531. invalidate();
  532. }
  533. peer.setMenuBar(menuBar);
  534. }
  535. }
  536. }
  537. }
  538. /**
  539. * Indicates whether this frame is resizable by the user.
  540. * By default, all frames are initially resizable.
  541. * @return <code>true</code> if the user can resize this frame;
  542. * <code>false</code> otherwise.
  543. * @see java.awt.Frame#setResizable(boolean)
  544. */
  545. public boolean isResizable() {
  546. return resizable;
  547. }
  548. /**
  549. * Sets whether this frame is resizable by the user.
  550. * @param resizable <code>true</code> if this frame is resizable;
  551. * <code>false</code> otherwise.
  552. * @see java.awt.Frame#isResizable
  553. */
  554. public void setResizable(boolean resizable) {
  555. boolean oldResizable = this.resizable;
  556. boolean testvalid = false;
  557. synchronized (this) {
  558. this.resizable = resizable;
  559. FramePeer peer = (FramePeer)this.peer;
  560. if (peer != null) {
  561. peer.setResizable(resizable);
  562. testvalid = true;
  563. }
  564. }
  565. // On some platforms, changing the resizable state affects
  566. // the insets of the Frame. If we could, we'd call invalidate()
  567. // from the peer, but we need to guarantee that we're not holding
  568. // the Frame lock when we call invalidate().
  569. if (testvalid && valid) {
  570. invalidate();
  571. }
  572. firePropertyChange("resizable", oldResizable, resizable);
  573. }
  574. /**
  575. * Sets the state of this frame (obsolete).
  576. * <p>
  577. * In older versions of JDK a frame state could only be NORMAL or
  578. * ICONIFIED. Since JDK 1.4 set of supported frame states is
  579. * expanded and frame state is represented as a bitwise mask.
  580. * <p>
  581. * For compatibility with old programs this method still accepts
  582. * <code>Frame.NORMAL</code> and <code>Frame.ICONIFIED</code> but
  583. * it only changes the iconic state of the frame, other aspects of
  584. * frame state are not affected by this method.
  585. *
  586. * @param state either <code>Frame.NORMAL</code> or
  587. * <code>Frame.ICONIFIED</code>.
  588. * @see #getState
  589. * @see #setExtendedState(int)
  590. */
  591. public synchronized void setState(int state) {
  592. int current = getExtendedState();
  593. if (state == ICONIFIED && (current & ICONIFIED) == 0) {
  594. setExtendedState(current | ICONIFIED);
  595. }
  596. else if (state == NORMAL && (current & ICONIFIED) != 0) {
  597. setExtendedState(current & ~ICONIFIED);
  598. }
  599. }
  600. /**
  601. * Sets the state of this frame. The state is
  602. * represented as a bitwise mask.
  603. * <ul>
  604. * <li><code>NORMAL</code>
  605. * <br>Indicates that no state bits are set.
  606. * <li><code>ICONIFIED</code>
  607. * <li><code>MAXIMIZED_HORIZ</code>
  608. * <li><code>MAXIMIZED_VERT</code>
  609. * <li><code>MAXIMIZED_BOTH</code>
  610. * <br>Concatenates <code>MAXIMIZED_HORIZ</code>
  611. * and <code>MAXIMIZED_VERT</code>.
  612. * </ul>
  613. * <p>Note that if the state is not supported on a
  614. * given platform, nothing will happen. The application
  615. * may determine if a specific state is available via
  616. * the <code>java.awt.Toolkit#isFrameStateSupported(int state)</code>
  617. * method.
  618. *
  619. * @param state a bitwise mask of frame state constants
  620. * @see #getExtendedState
  621. * @see java.awt.Toolkit#isFrameStateSupported(int)
  622. * @since 1.4
  623. */
  624. public synchronized void setExtendedState(int state) {
  625. this.state = state;
  626. FramePeer peer = (FramePeer)this.peer;
  627. if (peer != null) {
  628. peer.setState(state);
  629. }
  630. }
  631. /**
  632. * Gets the state of this frame (obsolete).
  633. * <p>
  634. * In older versions of JDK a frame state could only be NORMAL or
  635. * ICONIFIED. Since JDK 1.4 set of supported frame states is
  636. * expanded and frame state is represented as a bitwise mask.
  637. * <p>
  638. * For compatibility with old programs this method still returns
  639. * <code>Frame.NORMAL</code> and <code>Frame.ICONIFIED</code> but
  640. * it only reports the iconic state of the frame, other aspects of
  641. * frame state are not reported by this method.
  642. *
  643. * @return <code>Frame.NORMAL</code> or <code>Frame.ICONIFIED</code>.
  644. * @see #setState(int)
  645. * @see #getExtendedState
  646. */
  647. public synchronized int getState() {
  648. return (getExtendedState() & ICONIFIED) != 0 ? ICONIFIED : NORMAL;
  649. }
  650. /**
  651. * Gets the state of this frame. The state is
  652. * represented as a bitwise mask.
  653. * <ul>
  654. * <li><code>NORMAL</code>
  655. * <br>Indicates that no state bits are set.
  656. * <li><code>ICONIFIED</code>
  657. * <li><code>MAXIMIZED_HORIZ</code>
  658. * <li><code>MAXIMIZED_VERT</code>
  659. * <li><code>MAXIMIZED_BOTH</code>
  660. * <br>Concatenates <code>MAXIMIZED_HORIZ</code>
  661. * and <code>MAXIMIZED_VERT</code>.
  662. * </ul>
  663. *
  664. * @return a bitwise mask of frame state constants
  665. * @see #setExtendedState(int)
  666. * @since 1.4
  667. */
  668. public synchronized int getExtendedState() {
  669. FramePeer peer = (FramePeer)this.peer;
  670. if (peer != null) {
  671. state = peer.getState();
  672. }
  673. return state;
  674. }
  675. /**
  676. * Sets the maximized bounds for this frame.
  677. * <p>
  678. * When a frame is in maximized state the system supplies some
  679. * defaults bounds. This method allows some or all of those
  680. * system supplied values to be overridden.
  681. * <p>
  682. * If <code>bounds</code> is <code>null</code>, accept bounds
  683. * supplied by the system. If non-<code>null</code> you can
  684. * override some of the system supplied values while accepting
  685. * others by setting those fields you want to accept from system
  686. * to <code>Integer.MAX_VALUE</code>.
  687. * <p>
  688. * On some systems only the size portion of the bounds is taken
  689. * into account.
  690. *
  691. * @param bounds bounds for the maximized state
  692. * @see #getMaximizedBounds()
  693. * @since 1.4
  694. */
  695. public synchronized void setMaximizedBounds(Rectangle bounds) {
  696. this.maximizedBounds = bounds;
  697. FramePeer peer = (FramePeer)this.peer;
  698. if (peer != null) {
  699. peer.setMaximizedBounds(bounds);
  700. }
  701. }
  702. /**
  703. * Gets maximized bounds for this frame.
  704. * Some fields may contain <code>Integer.MAX_VALUE</code> to indicate
  705. * that system supplied values for this field must be used.
  706. *
  707. * @return maximized bounds for this frame; may be <code>null</code>
  708. * @see #setMaximizedBounds(Rectangle)
  709. * @since 1.4
  710. */
  711. public Rectangle getMaximizedBounds() {
  712. return maximizedBounds;
  713. }
  714. /**
  715. * Disables or enables decorations for this frame.
  716. * This method can only be called while the frame is not displayable.
  717. * @param undecorated <code>true</code> if no frame decorations are
  718. * to be enabled;
  719. * <code>false</code> if frame decorations are to be enabled.
  720. * @throws <code>IllegalComponentStateException</code> if the frame
  721. * is displayable.
  722. * @see #isUndecorated
  723. * @see Component#isDisplayable
  724. * @see javax.swing.JFrame#setDefaultLookAndFeelDecorated(boolean)
  725. * @since 1.4
  726. */
  727. public void setUndecorated(boolean undecorated) {
  728. /* Make sure we don't run in the middle of peer creation.*/
  729. synchronized (getTreeLock()) {
  730. if (isDisplayable()) {
  731. throw new IllegalComponentStateException("The frame is displayable.");
  732. }
  733. this.undecorated = undecorated;
  734. }
  735. }
  736. /**
  737. * Indicates whether this frame is undecorated.
  738. * By default, all frames are initially decorated.
  739. * @return <code>true</code> if frame is undecorated;
  740. * <code>false</code> otherwise.
  741. * @see java.awt.Frame#setUndecorated(boolean)
  742. * @since 1.4
  743. */
  744. public boolean isUndecorated() {
  745. return undecorated;
  746. }
  747. /**
  748. * Removes the specified menu bar from this frame.
  749. * @param m the menu component to remove.
  750. * If <code>m</code> is <code>null</code>, then
  751. * no action is taken
  752. */
  753. public void remove(MenuComponent m) {
  754. synchronized (getTreeLock()) {
  755. if (m == menuBar) {
  756. menuBar = null;
  757. FramePeer peer = (FramePeer)this.peer;
  758. if (peer != null) {
  759. mbManagement = true;
  760. if (valid) {
  761. invalidate();
  762. }
  763. peer.setMenuBar(null);
  764. m.removeNotify();
  765. }
  766. m.parent = null;
  767. } else {
  768. super.remove(m);
  769. }
  770. }
  771. }
  772. /**
  773. * Makes this Frame undisplayable by removing its connection
  774. * to its native screen resource. Making a Frame undisplayable
  775. * will cause any of its children to be made undisplayable.
  776. * This method is called by the toolkit internally and should
  777. * not be called directly by programs.
  778. * @see Component#isDisplayable
  779. * @see #addNotify
  780. */
  781. public void removeNotify() {
  782. synchronized (getTreeLock()) {
  783. FramePeer peer = (FramePeer)this.peer;
  784. if (peer != null) {
  785. // get the latest Frame state before disposing
  786. getState();
  787. if (menuBar != null) {
  788. mbManagement = true;
  789. peer.setMenuBar(null);
  790. menuBar.removeNotify();
  791. }
  792. }
  793. super.removeNotify();
  794. }
  795. }
  796. void postProcessKeyEvent(KeyEvent e) {
  797. if (menuBar != null && menuBar.handleShortcut(e)) {
  798. e.consume();
  799. return;
  800. }
  801. super.postProcessKeyEvent(e);
  802. }
  803. /**
  804. * Returns a string representing the state of this <code>Frame</code>.
  805. * This method is intended to be used only for debugging purposes, and the
  806. * content and format of the returned string may vary between
  807. * implementations. The returned string may be empty but may not be
  808. * <code>null</code>.
  809. *
  810. * @return the parameter string of this frame
  811. */
  812. protected String paramString() {
  813. String str = super.paramString();
  814. if (title != null) {
  815. str += ",title=" + title;
  816. }
  817. if (resizable) {
  818. str += ",resizable";
  819. }
  820. getExtendedState(); // sync with peer
  821. if (state == NORMAL) {
  822. str += ",normal";
  823. }
  824. else {
  825. if ((state & ICONIFIED) != 0) {
  826. str += ",iconified";
  827. }
  828. if ((state & MAXIMIZED_BOTH) == MAXIMIZED_BOTH) {
  829. str += ",maximized";
  830. }
  831. else if ((state & MAXIMIZED_HORIZ) != 0) {
  832. str += ",maximized_horiz";
  833. }
  834. else if ((state & MAXIMIZED_VERT) != 0) {
  835. str += ",maximized_vert";
  836. }
  837. }
  838. return str;
  839. }
  840. /**
  841. * @deprecated As of JDK version 1.1,
  842. * replaced by <code>Component.setCursor(Cursor)</code>.
  843. */
  844. public void setCursor(int cursorType) {
  845. if (cursorType < DEFAULT_CURSOR || cursorType > MOVE_CURSOR) {
  846. throw new IllegalArgumentException("illegal cursor type");
  847. }
  848. setCursor(Cursor.getPredefinedCursor(cursorType));
  849. }
  850. /**
  851. * @deprecated As of JDK version 1.1,
  852. * replaced by <code>Component.getCursor()</code>.
  853. */
  854. public int getCursorType() {
  855. return (getCursor().getType());
  856. }
  857. /**
  858. * Returns an array containing all Frames created by the application.
  859. * If called from an applet, the array will only include the Frames
  860. * accessible by that applet.
  861. * @since 1.2
  862. */
  863. public static Frame[] getFrames() {
  864. synchronized (Frame.class) {
  865. Frame realCopy[];
  866. Vector frameList =
  867. (Vector)AppContext.getAppContext().get(Frame.class);
  868. if (frameList != null) {
  869. // Recall that frameList is actually a Vector of WeakReferences
  870. // and calling get() on one of these references may return
  871. // null. Make two arrays-- one the size of the Vector
  872. // (fullCopy with size fullSize), and one the size of all
  873. // non-null get()s (realCopy with size realSize).
  874. int fullSize = frameList.size();
  875. int realSize = 0;
  876. Frame fullCopy[] = new Frame[fullSize];
  877. for (int i = 0; i < fullSize; i++) {
  878. fullCopy[realSize] = (Frame)
  879. (((WeakReference) (frameList.elementAt(i))).get());
  880. if (fullCopy[realSize] != null) {
  881. realSize++;
  882. }
  883. }
  884. if (fullSize != realSize) {
  885. realCopy = new Frame[realSize];
  886. System.arraycopy(fullCopy, 0, realCopy, 0, realSize);
  887. } else {
  888. realCopy = fullCopy;
  889. }
  890. } else {
  891. realCopy = new Frame[0];
  892. }
  893. return realCopy;
  894. }
  895. }
  896. void addToFrameList() {
  897. synchronized (Frame.class) {
  898. Vector frameList = (Vector)appContext.get(Frame.class);
  899. if (frameList == null) {
  900. frameList = new Vector();
  901. appContext.put(Frame.class, frameList);
  902. }
  903. frameList.addElement(weakThis);
  904. }
  905. }
  906. void removeFromFrameList() {
  907. synchronized (Frame.class) {
  908. Vector frameList = (Vector)appContext.get(Frame.class);
  909. if (frameList != null) {
  910. frameList.removeElement(weakThis);
  911. }
  912. }
  913. }
  914. /* Serialization support. If there's a MenuBar we restore
  915. * its (transient) parent field here. Likewise for top level
  916. * windows that are "owned" by this frame.
  917. */
  918. /**
  919. * <code>Frame</code>'s Serialized Data Version.
  920. *
  921. * @serial
  922. */
  923. private int frameSerializedDataVersion = 1;
  924. /**
  925. * Writes default serializable fields to stream. Writes
  926. * an optional serializable <code>Icon</code>, which is
  927. * available as of 1.4.
  928. *
  929. * @param s the <code>ObjectOutputStream</code> to write
  930. * @serialData an optional <code>Icon</code>
  931. * @see javax.swing.Icon
  932. * @see #readObject(ObjectInputStream)
  933. */
  934. private void writeObject(ObjectOutputStream s)
  935. throws IOException
  936. {
  937. s.defaultWriteObject();
  938. if (icon instanceof Serializable) {
  939. s.writeObject(icon);
  940. }
  941. else
  942. {
  943. s.writeObject(null);
  944. }
  945. }
  946. /**
  947. * Reads the <code>ObjectInputStream</code>. Tries
  948. * to read an <code>Icon</code>, which is optional
  949. * data available as of 1.4. If an <code>Icon</code>
  950. * is not available, but anything other than an EOF
  951. * is detected, an <code>OptionalDataException</code>
  952. * will be thrown..
  953. * Unrecognized keys or values will be ignored.
  954. *
  955. * @param s the <code>ObjectInputStream</code> to read
  956. * @exception OptionalDataException if an <code>Icon</code>
  957. * is not available, but anything other than an EOF
  958. * is detected
  959. * @exception HeadlessException if
  960. * <code>GraphicsEnvironment.isHeadless</code> returns
  961. * <code>true</code>
  962. * @see java.awt.GraphicsEnvironment#isHeadless()
  963. * @see javax.swing.Icon
  964. * @see #writeObject(ObjectOutputStream)
  965. */
  966. private void readObject(ObjectInputStream s)
  967. throws ClassNotFoundException, IOException, HeadlessException
  968. {
  969. // HeadlessException is thrown by Window's readObject
  970. s.defaultReadObject();
  971. try {
  972. icon = (Image) s.readObject();
  973. } catch (java.io.OptionalDataException e) {
  974. // pre-1.4 instances will not have this optional data.
  975. // e.eof will be true to indicate that there is no more
  976. // data available for this object.
  977. // If e.eof is not true, throw the exception as it
  978. // might have been caused by unrelated reasons.
  979. if (!e.eof) {
  980. throw (e);
  981. }
  982. }
  983. if (menuBar != null)
  984. menuBar.parent = this;
  985. // Ensure 1.1 serialized Frames can read & hook-up
  986. // owned windows properly
  987. //
  988. if (ownedWindows != null) {
  989. for (int i = 0; i < ownedWindows.size(); i++) {
  990. connectOwnedWindow((Window) ownedWindows.elementAt(i));
  991. }
  992. ownedWindows = null;
  993. }
  994. weakThis = new WeakReference(this);
  995. addToFrameList();
  996. }
  997. /**
  998. * Initialize JNI field and method IDs
  999. */
  1000. private static native void initIDs();
  1001. /*
  1002. * --- Accessibility Support ---
  1003. *
  1004. */
  1005. /**
  1006. * Gets the AccessibleContext associated with this Frame.
  1007. * For frames, the AccessibleContext takes the form of an
  1008. * AccessibleAWTFrame.
  1009. * A new AccessibleAWTFrame instance is created if necessary.
  1010. *
  1011. * @return an AccessibleAWTFrame that serves as the
  1012. * AccessibleContext of this Frame
  1013. */
  1014. public AccessibleContext getAccessibleContext() {
  1015. if (accessibleContext == null) {
  1016. accessibleContext = new AccessibleAWTFrame();
  1017. }
  1018. return accessibleContext;
  1019. }
  1020. /**
  1021. * This class implements accessibility support for the
  1022. * <code>Frame</code> class. It provides an implementation of the
  1023. * Java Accessibility API appropriate to frame user-interface elements.
  1024. */
  1025. protected class AccessibleAWTFrame extends AccessibleAWTWindow {
  1026. /**
  1027. * Get the role of this object.
  1028. *
  1029. * @return an instance of AccessibleRole describing the role of the
  1030. * object
  1031. * @see AccessibleRole
  1032. */
  1033. public AccessibleRole getAccessibleRole() {
  1034. return AccessibleRole.FRAME;
  1035. }
  1036. /**
  1037. * Get the state of this object.
  1038. *
  1039. * @return an instance of AccessibleStateSet containing the current
  1040. * state set of the object
  1041. * @see AccessibleState
  1042. */
  1043. public AccessibleStateSet getAccessibleStateSet() {
  1044. AccessibleStateSet states = super.getAccessibleStateSet();
  1045. if (getFocusOwner() != null) {
  1046. states.add(AccessibleState.ACTIVE);
  1047. }
  1048. if (isResizable()) {
  1049. states.add(AccessibleState.RESIZABLE);
  1050. }
  1051. return states;
  1052. }
  1053. } // inner class AccessibleAWTFrame
  1054. }