1. /*
  2. * @(#)JInternalFrame.java 1.95 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import java.beans.PropertyVetoException;
  11. import java.beans.PropertyChangeEvent;
  12. import java.util.EventListener;
  13. import javax.swing.border.Border;
  14. import javax.swing.event.InternalFrameEvent;
  15. import javax.swing.event.InternalFrameListener;
  16. import javax.swing.plaf.*;
  17. import javax.accessibility.*;
  18. import java.io.ObjectOutputStream;
  19. import java.io.ObjectInputStream;
  20. import java.io.IOException;
  21. /**
  22. * A lightweight object that provides many of the features of
  23. * a native frame, including dragging, closing, becoming an icon,
  24. * resizing, title display, and support for a menu bar. Generally,
  25. * you create an instance and add it to a JDesktopPane. Look and
  26. * feel specific-actions are then (automatically??) delegated to the
  27. * DesktopManager object maintained by the JDesktopPane (as set by
  28. * the UI).
  29. * <p>
  30. * The JInternalFrame <code>contentPane</code> is where you add child components.
  31. * So, to create a JInternalFrame that has a number of buttons arranged
  32. * with a BorderLayout object, you might do something like this:
  33. * <PRE>
  34. * JComponent c = (JComponent) frame.getContentPane();
  35. * c.setLayout(new BorderLayout());
  36. * c.add(new JButton(), BorderLayout.NORTH);
  37. * c.add(new JButton(), BorderLayout.CENTER);
  38. * </PRE>
  39. * The <code>contentPane</code> is actually managed by an instance of JRootPane,
  40. * which also manages a <code>layoutPane</code>, <code>glassPane</code>, and
  41. * optional <code>menuBar</code> for the frame. Please see the JRootPane
  42. * documentation for a complete description of these components.
  43. * <p>
  44. * For the keyboard keys used by this component in the standard Look and
  45. * Feel (L&F) renditions, see the
  46. * <a href="doc-files/Key-Index.html#JInternalFrame">JInternalFrame</a> key assignments.
  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 appropriate
  51. * for short term storage or RMI between applications running the same
  52. * version of Swing. A future release of Swing will provide support for
  53. * long term persistence.
  54. *
  55. * @see JDesktopPane
  56. * @see DesktopManager
  57. * @see JInternalFrame.JDesktopIcon
  58. * @see JRootPane
  59. *
  60. * @version 1.95 11/29/01
  61. * @author David Kloba
  62. * @author Rich Schiavi
  63. * @beaninfo
  64. * attribute: isContainer true
  65. * attribute: containerDelegate getContentPane
  66. * description: A frame container which is contained within
  67. * another window.
  68. */
  69. public class JInternalFrame extends JComponent implements
  70. Accessible, WindowConstants,
  71. RootPaneContainer
  72. {
  73. /**
  74. * @see #getUIClassID
  75. * @see #readObject
  76. */
  77. private static final String uiClassID = "InternalFrameUI";
  78. /**
  79. * The JRootPane instance that manages the <code>contentPane</code>
  80. * and optional <code>menuBar</code> for this frame, as well as the
  81. * <code>glassPane</code>.
  82. *
  83. * @see JRootPane
  84. * @see RootPaneContainer
  85. */
  86. protected JRootPane rootPane;
  87. /**
  88. * If true then calls to <code>add</code> and <code>setLayout</code>
  89. * cause an exception to be thrown.
  90. */
  91. protected boolean rootPaneCheckingEnabled = false;
  92. /** The frame can be closed. */
  93. protected boolean closable;
  94. /** The frame has been closed. */
  95. protected boolean isClosed;
  96. /** The frame can be expanded to the size of the desktop pane. */
  97. protected boolean maximizable;
  98. /**
  99. * The frame has been expanded to its maximum size.
  100. * @see #maximizable
  101. */
  102. protected boolean isMaximum;
  103. /**
  104. * The frame can "iconized" (shrunk down and displayed as
  105. * an icon-image).
  106. * @see JInternalFrame.JDesktopIcon
  107. */
  108. protected boolean iconable;
  109. /**
  110. * The frame has been iconized.
  111. * @see #iconable
  112. */
  113. protected boolean isIcon;
  114. /** The frame's size can be changed. */
  115. protected boolean resizable;
  116. /** The frame is currently selected. */
  117. protected boolean isSelected;
  118. /** The icon shown in the top-left corner of the frame. */
  119. protected Icon frameIcon;
  120. /** The title displayed in the frame's title bar. */
  121. protected String title;
  122. /**
  123. * The icon that is displayed when the frame is iconized.
  124. * @see #iconable
  125. */
  126. protected JDesktopIcon desktopIcon;
  127. private boolean opened;
  128. private int defaultCloseOperation = HIDE_ON_CLOSE;
  129. /** Bound property name. */
  130. public final static String CONTENT_PANE_PROPERTY = "contentPane";
  131. /** Bound property name. */
  132. public final static String MENU_BAR_PROPERTY = "menuBar";
  133. /** Bound property name. */
  134. public final static String TITLE_PROPERTY = "title";
  135. /** Bound property name. */
  136. public final static String LAYERED_PANE_PROPERTY = "layeredPane";
  137. /** Bound property name. */
  138. public final static String ROOT_PANE_PROPERTY = "rootPane";
  139. /** Bound property name. */
  140. public final static String GLASS_PANE_PROPERTY = "glassPane";
  141. /** Bound property name. */
  142. public final static String FRAME_ICON_PROPERTY = "frameIcon";
  143. /** Constrained property name indicated that this frame has selected status. */
  144. public final static String IS_SELECTED_PROPERTY = "selected";
  145. /** Constrained property name indicating that the frame is closed. */
  146. public final static String IS_CLOSED_PROPERTY = "closed";
  147. /** Constrained property name indicating that the frame is maximized. */
  148. public final static String IS_MAXIMUM_PROPERTY = "maximum";
  149. /** Constrained property name indicating that the frame is iconified. */
  150. public final static String IS_ICON_PROPERTY = "icon";
  151. /**
  152. * Creates a non-resizable, non-closable, non-maximizable,
  153. * non-iconifiable JInternalFrame with no title.
  154. */
  155. public JInternalFrame() {
  156. this("", false, false, false, false);
  157. }
  158. /**
  159. * Creates a non-resizable, non-closable, non-maximizable,
  160. * non-iconifiable JInternalFrame with the specified title.
  161. *
  162. * @param title the String to display in the title bar.
  163. */
  164. public JInternalFrame(String title) {
  165. this(title, false, false, false, false);
  166. }
  167. /**
  168. * Creates a non-closable, non-maximizable, non-iconifiable
  169. * JInternalFrame with the specified title and with resizability
  170. * specified.
  171. *
  172. * @param title the String to display in the title bar.
  173. * @param resizable if true, the frame can be resized
  174. */
  175. public JInternalFrame(String title, boolean resizable) {
  176. this(title, resizable, false, false, false);
  177. }
  178. /**
  179. * Creates a non-maximizable, non-iconifiable JInternalFrame with the
  180. * specified title and with resizability and closability specified.
  181. *
  182. * @param title the String to display in the title bar.
  183. * @param resizable if true, the frame can be resized
  184. * @param closable if true, the frame can be closed
  185. */
  186. public JInternalFrame(String title, boolean resizable, boolean closable) {
  187. this(title, resizable, closable, false, false);
  188. }
  189. /**
  190. * Creates a non-iconifiable JInternalFrame with the specified title
  191. * and with resizability, closability, and maximizability specified.
  192. *
  193. * @param title the String to display in the title bar.
  194. * @param resizable if true, the frame can be resized
  195. * @param closable if true, the frame can be closed
  196. * @param maximizable if true, the frame can be maximized
  197. */
  198. public JInternalFrame(String title, boolean resizable, boolean closable,
  199. boolean maximizable) {
  200. this(title, resizable, closable, maximizable, false);
  201. }
  202. /**
  203. * Creates a JInternalFrame with the specified title and
  204. * with resizability, closability, maximizability, and iconifiability
  205. * specified.
  206. *
  207. * @param title the String to display in the title bar.
  208. * @param resizable if true, the frame can be resized
  209. * @param closable if true, the frame can be closed
  210. * @param maximizable if true, the frame can be maximized
  211. * @param iconifiable if true, the frame can be iconified
  212. */
  213. public JInternalFrame(String title, boolean resizable, boolean closable,
  214. boolean maximizable, boolean iconifiable) {
  215. setRootPane(createRootPane());
  216. setLayout(new BorderLayout());
  217. this.title = title;
  218. this.resizable = resizable;
  219. this.closable = closable;
  220. this.maximizable = maximizable;
  221. isMaximum = false;
  222. this.iconable = iconifiable;
  223. isIcon = false;
  224. setRootPaneCheckingEnabled(true);
  225. desktopIcon = new JDesktopIcon(this);
  226. updateUI();
  227. }
  228. /**
  229. * Called by the constructor to set up the JRootPane.
  230. * @see JRootPane
  231. */
  232. protected JRootPane createRootPane() {
  233. return new JRootPane();
  234. }
  235. /**
  236. * Returns the L&F object that renders this component.
  237. *
  238. * @return the InternalFrameUI object that renders this component
  239. */
  240. public InternalFrameUI getUI() {
  241. return (InternalFrameUI)ui;
  242. }
  243. /**
  244. * Sets the UI delegate for this JInternalFrame.
  245. * @beaninfo
  246. * expert: true
  247. * description: The InternalFrameUI implementation that
  248. * defines the labels look and feel.
  249. */
  250. public void setUI(InternalFrameUI ui) {
  251. boolean checkingEnabled = isRootPaneCheckingEnabled();
  252. try {
  253. setRootPaneCheckingEnabled(false);
  254. super.setUI(ui);
  255. }
  256. finally {
  257. setRootPaneCheckingEnabled(checkingEnabled);
  258. }
  259. }
  260. /**
  261. * Notification from the UIManager that the L&F has changed.
  262. * Replaces the current UI object with the latest version from the
  263. * UIManager.
  264. *
  265. * @see JComponent#updateUI
  266. */
  267. public void updateUI() {
  268. setUI((InternalFrameUI)UIManager.getUI(this));
  269. invalidate();
  270. if (desktopIcon != null) {
  271. desktopIcon.updateUIWhenHidden();
  272. }
  273. }
  274. /* This method is called if updateUI was called on the associated
  275. * JDesktopIcon. It's necessary to avoid infinite recursion.
  276. */
  277. void updateUIWhenHidden() {
  278. setUI((InternalFrameUI)UIManager.getUI(this));
  279. invalidate();
  280. Component[] children = getComponents();
  281. if (children != null) {
  282. for(int i = 0; i < children.length; i++) {
  283. SwingUtilities.updateComponentTreeUI(children[i]);
  284. }
  285. }
  286. }
  287. /**
  288. * Returns the name of the L&F class that renders this component.
  289. *
  290. * @return "InternalFrameUI"
  291. * @see JComponent#getUIClassID
  292. * @see UIDefaults#getUI
  293. * @beaninfo
  294. * description: UIClassID
  295. */
  296. public String getUIClassID() {
  297. return uiClassID;
  298. }
  299. /**
  300. * Returns whether calls to <code>add</code> and
  301. * <code>setLayout</code> cause an exception to be thrown.
  302. *
  303. * @return true if <code>add</code> and <code>setLayout</code>
  304. * are checked
  305. * @see #addImpl
  306. * @see #setLayout
  307. * @see #setRootPaneCheckingEnabled
  308. */
  309. protected boolean isRootPaneCheckingEnabled() {
  310. return rootPaneCheckingEnabled;
  311. }
  312. /**
  313. * Determines whether calls to <code>add</code> and
  314. * <code>setLayout</code> cause an exception to be thrown.
  315. *
  316. * @param enabled a boolean value, true if checking is to be
  317. * enabled, which cause the exceptions to be thrown
  318. *
  319. * @see #addImpl
  320. * @see #setLayout
  321. * @see #isRootPaneCheckingEnabled
  322. */
  323. protected void setRootPaneCheckingEnabled(boolean enabled) {
  324. rootPaneCheckingEnabled = enabled;
  325. }
  326. /**
  327. * Creates a runtime exception with a message like:
  328. * <pre>
  329. * "Do not use JFrame.add() use JFrame.getContentPane().add() instead"
  330. * </pre>
  331. *
  332. * @param op a String indicating the attempted operation. In the
  333. * example above, the operation string is "add"
  334. */
  335. private Error createRootPaneException(String op) {
  336. String type = getClass().getName();
  337. return new Error(
  338. "Do not use " + type + "." + op + "() use "
  339. + type + ".getContentPane()." + op + "() instead");
  340. }
  341. /**
  342. * By default, children may not be added directly to a this component,
  343. * they must be added to its contentPane instead. For example:
  344. * <pre>
  345. * thisComponent.getContentPane().add(child)
  346. * </pre>
  347. * An attempt to add to directly to this component will cause an
  348. * runtime exception to be thrown. Subclasses can disable this
  349. * behavior.
  350. *
  351. * @see #setRootPaneCheckingEnabled
  352. * @exception Error if called with rootPaneChecking true
  353. */
  354. protected void addImpl(Component comp, Object constraints, int index)
  355. {
  356. if(isRootPaneCheckingEnabled()) {
  357. throw createRootPaneException("add");
  358. }
  359. else {
  360. super.addImpl(comp, constraints, index);
  361. }
  362. }
  363. /**
  364. * Removes the specified component from this container.
  365. * @param comp the component to be removed
  366. * @see #add
  367. */
  368. public void remove(Component comp) {
  369. int oldCount = getComponentCount();
  370. super.remove(comp);
  371. if (oldCount == getComponentCount()) {
  372. // Client mistake, but we need to handle it to avoid a
  373. // common object leak in client applications.
  374. getContentPane().remove(comp);
  375. }
  376. }
  377. /**
  378. * By default the layout of this component may not be set,
  379. * the layout of its contentPane should be set instead.
  380. * For example:
  381. * <pre>
  382. * thiComponent.getContentPane().setLayout(new BorderLayout())
  383. * </pre>
  384. * An attempt to set the layout of this component will cause an
  385. * runtime exception to be thrown. Subclasses can disable this
  386. * behavior.
  387. *
  388. * @see #setRootPaneCheckingEnabled
  389. * @exception Error if called with rootPaneChecking true
  390. */
  391. public void setLayout(LayoutManager manager) {
  392. if(isRootPaneCheckingEnabled()) {
  393. throw createRootPaneException("setLayout");
  394. }
  395. else {
  396. super.setLayout(manager);
  397. }
  398. }
  399. //////////////////////////////////////////////////////////////////////////
  400. /// Property Methods
  401. //////////////////////////////////////////////////////////////////////////
  402. /**
  403. * Returns the current JMenuBar for this JInternalFrame, or null
  404. * if no menu bar has been set.
  405. *
  406. * @deprecated As of Swing version 1.0.3,
  407. * replaced by <code>getJMenuBar()</code>.
  408. */
  409. public JMenuBar getMenuBar() {
  410. return getRootPane().getMenuBar();
  411. }
  412. /**
  413. * Returns the current JMenuBar for this JInternalFrame, or null
  414. * if no menu bar has been set.
  415. *
  416. * @return the JMenuBar used by this frame
  417. * @see #setJMenuBar
  418. */
  419. public JMenuBar getJMenuBar() {
  420. return getRootPane().getJMenuBar();
  421. }
  422. /**
  423. * Sets the JMenuBar for this JInternalFrame.
  424. *
  425. * @param m the JMenuBar to use in this frame
  426. * @see #getJMenuBar
  427. * @deprecated As of Swing version 1.0.3
  428. * replaced by <code>setJMenuBar(JMenuBar m)</code>.
  429. */
  430. public void setMenuBar(JMenuBar m) {
  431. JMenuBar oldValue = getMenuBar();
  432. getRootPane().setJMenuBar(m);
  433. firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
  434. }
  435. /**
  436. * Sets the JMenuBar for this JInternalFrame.
  437. *
  438. * @param m the JMenuBar to use in this frame
  439. * @see #getJMenuBar
  440. * @beaninfo
  441. * preferred: true
  442. * description: The menubar for accessing pulldown menus
  443. * from this frame.
  444. */
  445. public void setJMenuBar(JMenuBar m){
  446. JMenuBar oldValue = getMenuBar();
  447. getRootPane().setJMenuBar(m);
  448. firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
  449. }
  450. // implements javax.swing.RootPaneContainer
  451. public Container getContentPane() {
  452. return getRootPane().getContentPane();
  453. }
  454. /**
  455. * Sets this JInternalFrame's content pane.
  456. *
  457. * @param contentPane the contentPane object for this frame
  458. *
  459. * @exception java.awt.IllegalComponentStateException (a runtime
  460. * exception) if the content pane parameter is null
  461. * @see RootPaneContainer#getContentPane
  462. * @beaninfo
  463. * bound: true
  464. * hidden: true
  465. * description: The client area of the frame where child
  466. * components are normally inserted.
  467. */
  468. public void setContentPane(Container c) {
  469. Container oldValue = getContentPane();
  470. getRootPane().setContentPane(c);
  471. firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
  472. }
  473. /**
  474. * Returns the layeredPane object for this frame.
  475. *
  476. * @see RootPaneContainer#setLayeredPane
  477. * @see RootPaneContainer#getLayeredPane
  478. */
  479. public JLayeredPane getLayeredPane() {
  480. return getRootPane().getLayeredPane();
  481. }
  482. /**
  483. * Sets this JInternalFrame's layeredPane property.
  484. * @param layeredPane the layeredPane object for this frame
  485. *
  486. * @exception java.awt.IllegalComponentStateException (a runtime
  487. * exception) if the layered pane parameter is null
  488. * @see RootPaneContainer#setLayeredPane
  489. * @beaninfo
  490. * hidden: true
  491. * bound: true
  492. * description: The pane which holds the various desktop layers.
  493. */
  494. public void setLayeredPane(JLayeredPane layered) {
  495. JLayeredPane oldValue = getLayeredPane();
  496. getRootPane().setLayeredPane(layered);
  497. firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
  498. }
  499. /**
  500. * Returns the glassPane object for this frame.
  501. *
  502. * @see RootPaneContainer#setGlassPane
  503. */
  504. public Component getGlassPane() {
  505. return getRootPane().getGlassPane();
  506. }
  507. /**
  508. * Sets this JInternalFrame's glassPane property.
  509. * @param glassPane the glassPane object for this frame
  510. * @see RootPaneContainer#getGlassPane
  511. * @beaninfo
  512. * hidden: true
  513. * description: A transparent pane used for menu rendering.
  514. */
  515. public void setGlassPane(Component glass) {
  516. Component oldValue = getGlassPane();
  517. getRootPane().setGlassPane(glass);
  518. firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
  519. }
  520. /**
  521. * Returns the rootPane object for this frame.
  522. *
  523. * @see RootPaneContainer#getRootPane
  524. */
  525. public JRootPane getRootPane() {
  526. return rootPane;
  527. }
  528. /**
  529. * Set the rootPane property. This method is called by the constructor.
  530. * @beaninfo
  531. * hidden: true
  532. * beaninfo: The rootPane used by this frame.
  533. */
  534. protected void setRootPane(JRootPane root) {
  535. if(rootPane != null) {
  536. remove(rootPane);
  537. }
  538. JRootPane oldValue = getRootPane();
  539. rootPane = root;
  540. if(rootPane != null) {
  541. boolean checkingEnabled = isRootPaneCheckingEnabled();
  542. try {
  543. setRootPaneCheckingEnabled(false);
  544. add(rootPane, BorderLayout.CENTER);
  545. }
  546. finally {
  547. setRootPaneCheckingEnabled(checkingEnabled);
  548. }
  549. }
  550. firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
  551. }
  552. /**
  553. * Set the visible state of the object.
  554. *
  555. * @param b if true, shows this object; otherwise, hides it
  556. */
  557. public void setVisible(boolean b) {
  558. super.setVisible(b);
  559. }
  560. /**
  561. * Set that this JInternalFrame can be closed by some user action.
  562. * @param b a boolean value, where true means the frame can be closed
  563. * @beaninfo
  564. * preferred: true
  565. * bound: true
  566. * description: Indicates whether this frame can be closed.
  567. */
  568. public void setClosable(boolean b) {
  569. Boolean oldValue = closable ? Boolean.TRUE : Boolean.FALSE;
  570. Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  571. closable = b;
  572. firePropertyChange("closable", oldValue, newValue);
  573. }
  574. /**
  575. * Returns whether this JInternalFrame be closed by some user action.
  576. * @return true if the frame can be closed
  577. */
  578. public boolean isClosable() {
  579. return closable;
  580. }
  581. /**
  582. * Returns whether this JInternalFrame is currently closed.
  583. * @return true if the frame is closed
  584. */
  585. public boolean isClosed() {
  586. return isClosed;
  587. }
  588. /**
  589. * Calling this method with a value of <code>true</code> to close
  590. * the frame.
  591. *
  592. * @param b a boolean, where true means "close the frame"
  593. * @exception PropertyVetoException when the attempt to set the
  594. * property is vetoed by the receiver.
  595. * @beaninfo
  596. * bound: true
  597. * constrained: true
  598. * description: Indicates that the frame has been closed.
  599. */
  600. public void setClosed(boolean b) throws PropertyVetoException {
  601. if (isClosed == b) {
  602. return;
  603. }
  604. Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE;
  605. Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  606. fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
  607. isClosed = b;
  608. if (isClosed) {
  609. /* Dispatch a closed event to any listeners. We can't post
  610. * an event since firing IS_CLOSED_PROPERTY causes this
  611. * frame to be removed from its parent, which causes any
  612. * of its events on the EventQueue to get purged.
  613. */
  614. fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
  615. fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
  616. opened = false;
  617. } else if (!opened) {
  618. fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
  619. opened = true;
  620. }
  621. firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
  622. }
  623. /**
  624. * Set that the JInternalFrame can be resized by some user action.
  625. *
  626. * @param b a boolean, where true means the frame can be resized
  627. * @beaninfo
  628. * preferred: true
  629. * bound: true
  630. * description: Determines whether the frame can be resized
  631. * by the user.
  632. */
  633. public void setResizable(boolean b) {
  634. Boolean oldValue = resizable ? Boolean.TRUE : Boolean.FALSE;
  635. Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  636. resizable = b;
  637. firePropertyChange("resizable", oldValue, newValue);
  638. }
  639. /**
  640. * Returns whether the JInternalFrame can be resized by some user action.
  641. *
  642. * @return true if the frame can be resized
  643. */
  644. public boolean isResizable() {
  645. // don't allow resizing when maximized.
  646. return isMaximum ? false : resizable;
  647. }
  648. /**
  649. * Set that the JInternalFrame can be made an icon by some user action.
  650. *
  651. * @param b a boolean, where true means the frame can be iconified
  652. * @beaninfo:
  653. * preferred: true
  654. * bound: true
  655. * description: Determines whether this frame can be iconified.
  656. */
  657. public void setIconifiable(boolean b) {
  658. iconable = b;
  659. }
  660. /**
  661. * Returns whether the JInternalFrame can be iconified by some user action.
  662. *
  663. * @return true if the frame can be iconified
  664. */
  665. public boolean isIconifiable() {
  666. return iconable;
  667. }
  668. /**
  669. * Returns whether the JInternalFrame is currently iconified.
  670. *
  671. * @return true if the frame is iconified
  672. */
  673. public boolean isIcon() {
  674. return isIcon;
  675. }
  676. /**
  677. * Iconizes and deconizes the frame.
  678. *
  679. * @param b a boolean, where true means to iconify the frame and
  680. * false means to deiconify it
  681. * @exception PropertyVetoException when the attempt to set the
  682. * property is vetoed by the receiver.
  683. * @beaninfo
  684. * bound: true
  685. * constrained: true
  686. * description: The image displayed when this frame is minimized.
  687. */
  688. public void setIcon(boolean b) throws PropertyVetoException {
  689. if (isIcon == b) {
  690. return;
  691. }
  692. Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE;
  693. Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  694. fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
  695. isIcon = b;
  696. firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
  697. if (b)
  698. fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
  699. else
  700. fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
  701. }
  702. /**
  703. * Set that the JInternalFrame can be maximized by some user action.
  704. *
  705. * @param b a boolean where true means the frame can be maximized
  706. * @beaninfo
  707. * bound: true
  708. * preferred: true
  709. * description: Determines whether this frame can be maximized.
  710. */
  711. public void setMaximizable(boolean b) {
  712. Boolean oldValue = maximizable ? Boolean.TRUE : Boolean.FALSE;
  713. Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  714. maximizable = b;
  715. firePropertyChange("maximizable", oldValue, newValue);
  716. }
  717. /**
  718. * Returns whether the JInternalFrame can be maximized by some user action.
  719. *
  720. * @return true if the frame can be maximized
  721. */
  722. public boolean isMaximizable() {
  723. return maximizable;
  724. }
  725. /**
  726. * Returns whether the JInternalFrame is currently maximized.
  727. *
  728. * @return true if the frame is maximized
  729. */
  730. public boolean isMaximum() {
  731. return isMaximum;
  732. }
  733. /**
  734. * Maximizes and restores the frame. A maximized frame is resized to
  735. * fully fit the JDesktopPane area associated with the JInternalFrame.
  736. * A restored frame's size is set to the JInternalFrame's actual size.
  737. *
  738. * @param b a boolean, where true maximizes the frame and false
  739. * restores it
  740. * @exception PropertyVetoException when the attempt to set the
  741. * property is vetoed by the receiver.
  742. * @beaninfo
  743. * constrained: true
  744. * description: Indicates whether the frame is maximized.
  745. */
  746. public void setMaximum(boolean b) throws PropertyVetoException {
  747. if (isMaximum == b) {
  748. return;
  749. }
  750. Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
  751. Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  752. fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
  753. isMaximum = b;
  754. firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
  755. }
  756. /**
  757. * Returns the title of the JInternalFrame.
  758. *
  759. * @return a String containing the frame's title
  760. * @see #setTitle
  761. */
  762. public String getTitle() {
  763. return title;
  764. }
  765. /**
  766. * Sets the JInternalFrame title.
  767. * @see #getTitle
  768. *
  769. * @param title the String to display in the title bar
  770. * @beaninfo:
  771. * preferred: true
  772. * bound: true
  773. * description: The text displayed in the title bar.
  774. */
  775. public void setTitle(String title) {
  776. String oldValue = this.title;
  777. this.title = title;
  778. firePropertyChange(TITLE_PROPERTY, oldValue, title);
  779. }
  780. /**
  781. * Selects and deselects the JInternalFrame.
  782. * A JInternalFrame normally draws it's title bar differently if it is
  783. * the selected frame, which indicates to the user that this
  784. * internalFrame has the focus.
  785. *
  786. * @param selected a boolean, where true means the frame is selected
  787. * (currently active) and false means it is not
  788. * @exception PropertyVetoException when the attempt to set the
  789. * property is vetoed by the receiver.
  790. * @beaninfo
  791. * constrained: true
  792. * bound: true
  793. * description: Indicates whether this frame is currently
  794. * the active frame.
  795. */
  796. public void setSelected(boolean selected) throws PropertyVetoException {
  797. if (isSelected == selected) {
  798. return;
  799. }
  800. Boolean oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
  801. Boolean newValue = selected ? Boolean.TRUE : Boolean.FALSE;
  802. fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
  803. isSelected = selected;
  804. firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
  805. if (isSelected)
  806. fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
  807. else
  808. fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
  809. repaint();
  810. }
  811. /**
  812. * Returns whether the JInternalFrame is the currently "selected" or
  813. * active frame.
  814. *
  815. * @return true if the frame is currently selected (active)
  816. * @see #setSelected
  817. */
  818. public boolean isSelected() {
  819. return isSelected;
  820. }
  821. /**
  822. * Sets an image to be displayed in the titlebar of the frame (usually
  823. * in the top-left corner).
  824. * This image is not the <code>desktopIcon</code> object, which
  825. * is the image displayed in the JDesktop when the frame is iconified.
  826. *
  827. * Passing null to this function is valid, but the L&F can choose the
  828. * appropriate behavior for that situation, such as displaying no icon
  829. * or a default icon for the L&F.
  830. *
  831. * @param icon the Icon to display in the title bar
  832. * @see #getFrameIcon
  833. * @beaninfo
  834. * bound: true
  835. * description: The icon shown in the top-left corner of the frame.
  836. */
  837. public void setFrameIcon(Icon icon) {
  838. Icon oldIcon = frameIcon;
  839. frameIcon = icon;
  840. firePropertyChange(FRAME_ICON_PROPERTY, oldIcon, icon);
  841. }
  842. /**
  843. * Returns the image displayed in the title bar of the frame (usually
  844. * in the top-left corner).
  845. *
  846. * @return the Icon displayed in the title bar
  847. * @see #setFrameIcon
  848. */
  849. public Icon getFrameIcon() {
  850. return frameIcon;
  851. }
  852. /** Convenience method that moves this component to position 0 if it's
  853. * parent is a JLayeredPane.
  854. */
  855. public void moveToFront() {
  856. if(getParent() != null && getParent() instanceof JLayeredPane) {
  857. JLayeredPane l = (JLayeredPane)getParent();
  858. l.moveToFront(this);
  859. }
  860. }
  861. /** Convenience method that moves this component to position -1 if it's
  862. * parent is a JLayeredPane.
  863. */
  864. public void moveToBack() {
  865. if(getParent() != null && getParent() instanceof JLayeredPane) {
  866. JLayeredPane l = (JLayeredPane)getParent();
  867. l.moveToBack(this);
  868. }
  869. }
  870. /**
  871. * Convenience method for setting the layer attribute of this component.
  872. *
  873. * @param layer an Integer object specifying this frame's desktop layer
  874. * @see JLayeredPane
  875. * @beaninfo
  876. * expert: true
  877. * description: Specifies what desktop layer is used.
  878. */
  879. public void setLayer(Integer layer) {
  880. if(getParent() != null && getParent() instanceof JLayeredPane) {
  881. // Normally we want to do this, as it causes the LayeredPane
  882. // to draw properly.
  883. JLayeredPane p = (JLayeredPane)getParent();
  884. p.setLayer(this, layer.intValue(), p.getPosition(this));
  885. } else {
  886. // Try to do the right thing
  887. JLayeredPane.putLayer(this, layer.intValue());
  888. if(getParent() != null)
  889. getParent().repaint(_bounds.x, _bounds.y,
  890. _bounds.width, _bounds.height);
  891. }
  892. }
  893. /** Convenience method for getting the layer attribute of this component.
  894. *
  895. * @return an Integer object specifying this frame's desktop layer
  896. * @see JLayeredPane
  897. */
  898. public int getLayer() {
  899. return JLayeredPane.getLayer(this);
  900. }
  901. /** Convenience method that searchs the anscestor heirarchy for a
  902. * JDesktop instance. If JInternalFrame finds none, the desktopIcon
  903. * tree is searched.
  904. *
  905. * @return the JDesktopPane this frame belongs to, or null if none
  906. * is found
  907. */
  908. public JDesktopPane getDesktopPane() {
  909. Container p;
  910. // Search upward for desktop
  911. p = getParent();
  912. while(p != null && !(p instanceof JDesktopPane))
  913. p = p.getParent();
  914. if(p == null) {
  915. // search it's icon parent for desktop
  916. p = getDesktopIcon().getParent();
  917. while(p != null && !(p instanceof JDesktopPane))
  918. p = p.getParent();
  919. }
  920. return (JDesktopPane)p;
  921. }
  922. /**
  923. * Sets the JDesktopIcon associated with this JInternalFrame.
  924. *
  925. * @param d the JDesktopIcon to display on the desktop
  926. * @see #getDesktopIcon
  927. * @beaninfo
  928. * bound: true
  929. * description: The icon shown when this frame is minimized.
  930. */
  931. public void setDesktopIcon(JDesktopIcon d) {
  932. JDesktopIcon oldValue = getDesktopIcon();
  933. desktopIcon = d;
  934. firePropertyChange("desktopIcon", oldValue, d);
  935. }
  936. /**
  937. * Returns the JDesktopIcon used when this JInternalFrame is iconified.
  938. *
  939. * @return the JDesktopIcon displayed on the desktop
  940. * @see #setDesktopIcon
  941. */
  942. public JDesktopIcon getDesktopIcon() {
  943. return desktopIcon;
  944. }
  945. /*
  946. * Creates a new EventDispatchThread to dispatch events from. This
  947. * method returns when stopModal is invoked.
  948. */
  949. synchronized void startModal() {
  950. /* Since all input will be blocked until this dialog is dismissed,
  951. * make sure its parent containers are visible first (this component
  952. * is tested below). This is necessary for JApplets, because
  953. * because an applet normally isn't made visible until after its
  954. * start() method returns -- if this method is called from start(),
  955. * the applet will appear to hang while an invisible modal frame
  956. * waits for input.
  957. */
  958. if (isVisible() && !isShowing()) {
  959. Container parent = this.getParent();
  960. while (parent != null) {
  961. if (parent.isVisible() == false) {
  962. parent.setVisible(true);
  963. }
  964. parent = parent.getParent();
  965. }
  966. }
  967. try {
  968. if (SwingUtilities.isEventDispatchThread()) {
  969. EventQueue theQueue = getToolkit().getSystemEventQueue();
  970. while (isVisible()) {
  971. // This is essentially the body of EventDispatchThread
  972. AWTEvent event = theQueue.getNextEvent();
  973. Object src = event.getSource();
  974. // can't call theQueue.dispatchEvent, so I pasted it's body here
  975. /*if (event instanceof ActiveEvent) {
  976. ((ActiveEvent) event).dispatch();
  977. } else */ if (src instanceof Component) {
  978. ((Component) src).dispatchEvent(event);
  979. } else if (src instanceof MenuComponent) {
  980. ((MenuComponent) src).dispatchEvent(event);
  981. } else {
  982. System.err.println("unable to dispatch event: " + event);
  983. }
  984. }
  985. } else
  986. while (isVisible())
  987. wait();
  988. } catch(InterruptedException e){}
  989. }
  990. /*
  991. * Stops the event dispatching loop created by a previous call to
  992. * <code>startModal</code>.
  993. */
  994. synchronized void stopModal() {
  995. notifyAll();
  996. }
  997. /**
  998. * Moves and resizes this component. Unlike other components,
  999. * this implementation also forces re-layout, so that frame
  1000. * decorations such as the title bar are always redisplayed.
  1001. *
  1002. * @param x an int giving the component's new horizontal position
  1003. * measured in pixels from the left of its container
  1004. * @param y an int giving the component's new vertical position,
  1005. * measured in pixels from the bottom of its container
  1006. * @param width an int giving the component's new width in pixels
  1007. * @param height an int giving the component's new height in pixels
  1008. */
  1009. public void reshape(int x, int y, int width, int height) {
  1010. super.reshape(x, y, width, height);
  1011. validate();
  1012. repaint();
  1013. }
  1014. ///////////////////////////
  1015. // Frame/Window equivalents
  1016. ///////////////////////////
  1017. /**
  1018. * Adds the specified internal frame listener to receive internal frame events from
  1019. * this internal frame.
  1020. * @param l the internal frame listener
  1021. */
  1022. public void addInternalFrameListener(InternalFrameListener l) { // remind: sync ??
  1023. listenerList.add(InternalFrameListener.class, l);
  1024. // remind: needed?
  1025. enableEvents(0); // turn on the newEventsOnly flag in Component.
  1026. }
  1027. /**
  1028. * Removes the specified internal frame listener so that it no longer
  1029. * receives internal frame events from this internal frame.
  1030. * @param l the internal frame listener
  1031. */
  1032. public void removeInternalFrameListener(InternalFrameListener l) { // remind: sync??
  1033. listenerList.remove(InternalFrameListener.class, l);
  1034. }
  1035. // remind: name ok? all one method ok? need to be synchronized?
  1036. protected void fireInternalFrameEvent(int id){
  1037. Object[] listeners = listenerList.getListenerList();
  1038. InternalFrameEvent e = null;
  1039. for (int i = listeners.length -2; i >=0; i -= 2){
  1040. if (listeners[i] == InternalFrameListener.class){
  1041. if (e == null){
  1042. e = new InternalFrameEvent(this, id);
  1043. // System.out.println("InternalFrameEvent: " + e.paramString());
  1044. }
  1045. switch(e.getID()) {
  1046. case InternalFrameEvent.INTERNAL_FRAME_OPENED:
  1047. ((InternalFrameListener)listeners[i+1]).internalFrameOpened(e);
  1048. break;
  1049. case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
  1050. ((InternalFrameListener)listeners[i+1]).internalFrameClosing(e);
  1051. break;
  1052. case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
  1053. ((InternalFrameListener)listeners[i+1]).internalFrameClosed(e);
  1054. break;
  1055. case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
  1056. ((InternalFrameListener)listeners[i+1]).internalFrameIconified(e);
  1057. break;
  1058. case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
  1059. ((InternalFrameListener)listeners[i+1]).internalFrameDeiconified(e);
  1060. break;
  1061. case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
  1062. ((InternalFrameListener)listeners[i+1]).internalFrameActivated(e);
  1063. break;
  1064. case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
  1065. ((InternalFrameListener)listeners[i+1]).internalFrameDeactivated(e);
  1066. break;
  1067. default:
  1068. break;
  1069. }
  1070. }
  1071. }
  1072. if (id == InternalFrameEvent.INTERNAL_FRAME_CLOSING) {
  1073. doDefaultCloseAction();
  1074. }
  1075. }
  1076. private void doDefaultCloseAction() {
  1077. switch(defaultCloseOperation) {
  1078. case HIDE_ON_CLOSE:
  1079. try {
  1080. setClosed(true);
  1081. } catch (PropertyVetoException pve) {}
  1082. break;
  1083. case DISPOSE_ON_CLOSE:
  1084. try {
  1085. setClosed(true);
  1086. dispose(); // only executes if close wasn't vetoed.
  1087. } catch (PropertyVetoException pve) {}
  1088. break;
  1089. case 3: // EXIT_ON_CLOSE:
  1090. System.exit(0);
  1091. break;
  1092. case DO_NOTHING_ON_CLOSE:
  1093. default:
  1094. break;
  1095. }
  1096. }
  1097. /**
  1098. * Sets the operation which will happen by default when
  1099. * the user initiates a "close" on this window.
  1100. * The possible choices are:
  1101. * <p>
  1102. * <ul>
  1103. * <li>DO_NOTHING_ON_CLOSE - do not do anything - require the
  1104. * program to handle the operation in the windowClosing
  1105. * method of a registered InternalFrameListener object.
  1106. * <li>HIDE_ON_CLOSE - automatically hide the window after
  1107. * invoking any registered InternalFrameListener objects
  1108. * <li>DISPOSE_ON_CLOSE - automatically hide and dispose the
  1109. * window after invoking any registered InternalFrameListener objects
  1110. * <li>EXIT_ON_CLOSE - Exit the application by way of System.exit.
  1111. * Only use this in applications.
  1112. * </ul>
  1113. * <p>
  1114. * The value is set to HIDE_ON_CLOSE by default.
  1115. * @see #addInternalFrameListener
  1116. * @see #getDefaultCloseOperation
  1117. */
  1118. public void setDefaultCloseOperation(int operation) {
  1119. this.defaultCloseOperation = operation;
  1120. }
  1121. /**
  1122. * Returns the default operation which occurs when the user
  1123. * initiates a "close" on this window.
  1124. * @see #setDefaultCloseOperation
  1125. */
  1126. public int getDefaultCloseOperation() {
  1127. return defaultCloseOperation;
  1128. }
  1129. /**
  1130. * Causes subcomponents of this JInternalFrame to be laid out at their
  1131. * preferred size.
  1132. * @see java.awt.Window#pack
  1133. */
  1134. public void pack() {
  1135. Container parent = getParent();
  1136. if (parent != null && parent.getPeer() == null) {
  1137. parent.addNotify();
  1138. addNotify();
  1139. }
  1140. setSize(getPreferredSize());
  1141. validate();
  1142. }
  1143. /**
  1144. * Shows this internal frame, and brings it to the front.
  1145. * <p>
  1146. * If this window is not yet visible, <code>show</code>
  1147. * makes it visible. If this window is already visible,
  1148. * then this method brings it to the front.
  1149. * @see java.awt.Window#show
  1150. * @see java.awt.Window#toFront
  1151. * @see java.awt.Component#setVisible
  1152. */
  1153. public void show() {
  1154. Container parent = getParent();
  1155. if (parent != null && parent.getPeer() == null) {
  1156. parent.addNotify();
  1157. addNotify();
  1158. }
  1159. validate();
  1160. // bug 4149505
  1161. if (!opened) {
  1162. fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
  1163. opened = true;
  1164. }
  1165. if (isVisible()) {
  1166. toFront();
  1167. } else {
  1168. super.show();
  1169. }
  1170. if (!isSelected()) {
  1171. try {
  1172. setSelected(true);
  1173. } catch (PropertyVetoException pve) {}
  1174. }
  1175. }
  1176. /**
  1177. * Disposes of this internal frame. If the frame is not already
  1178. * closed, a frame-closed event is posted.
  1179. */
  1180. public void dispose() {
  1181. if (isVisible()) {
  1182. setVisible(false);
  1183. }
  1184. if (isSelected()) {
  1185. try {
  1186. setSelected(false);
  1187. } catch (PropertyVetoException pve) {}
  1188. }
  1189. if (!isClosed) {
  1190. firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE);
  1191. fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
  1192. }
  1193. }
  1194. /**
  1195. * Brings this internal frame to the front.
  1196. * Places this internal frame at the top of the stacking order
  1197. * and makes the corresponding adjustment to other visible windows.
  1198. * @see java.awt.Window#toFront
  1199. * @see #moveToFront
  1200. */
  1201. public void toFront() {
  1202. moveToFront();
  1203. }
  1204. /**
  1205. * Sends this internal frame to the back.
  1206. * Places this internal frame at the bottom of the stacking order
  1207. * and makes the corresponding adjustment to other visible windows.
  1208. * @see java.awt.Window#toBack
  1209. * @see #moveToBack
  1210. */
  1211. public void toBack() {
  1212. moveToBack();
  1213. }
  1214. /**
  1215. * Gets the warning string that is displayed with this window.
  1216. * Since an internal frame is always secure (since it's fully
  1217. * contained within a window which might need a warning string)
  1218. * this method always returns null.
  1219. * @return null
  1220. * @see java.awt.Window#getWarningString
  1221. */
  1222. public final String getWarningString() {
  1223. return null;
  1224. }
  1225. /**
  1226. * See readObject() and writeObject() in JComponent for more
  1227. * information about serialization in Swing.
  1228. */
  1229. private void writeObject(ObjectOutputStream s) throws IOException {
  1230. s.defaultWriteObject();
  1231. if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  1232. boolean old = isRootPaneCheckingEnabled();
  1233. try {
  1234. setRootPaneCheckingEnabled(false);
  1235. ui.installUI(this);
  1236. }
  1237. finally {
  1238. setRootPaneCheckingEnabled(old);
  1239. }
  1240. }
  1241. }
  1242. /**
  1243. * Returns a string representation of this JInternalFrame. This method
  1244. * is intended to be used only for debugging purposes, and the
  1245. * content and format of the returned string may vary between
  1246. * implementations. The returned string may be empty but may not
  1247. * be <code>null</code>.
  1248. *
  1249. * @return a string representation of this JInternalFrame.
  1250. */
  1251. protected String paramString() {
  1252. String rootPaneString = (rootPane != null ?
  1253. rootPane.toString() : "");
  1254. String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
  1255. "true" : "false");
  1256. String closableString = (closable ? "true" : "false");
  1257. String isClosedString = (isClosed ? "true" : "false");
  1258. String maximizableString = (maximizable ? "true" : "false");
  1259. String isMaximumString = (isMaximum ? "true" : "false");
  1260. String iconableString = (iconable ? "true" : "false");
  1261. String isIconString = (isIcon ? "true" : "false");
  1262. String resizableString = (resizable ? "true" : "false");
  1263. String isSelectedString = (isSelected ? "true" : "false");
  1264. String frameIconString = (frameIcon != null ?
  1265. frameIcon.toString() : "");
  1266. String titleString = (title != null ?
  1267. title : "");
  1268. String desktopIconString = (desktopIcon != null ?
  1269. desktopIcon.toString() : "");
  1270. String openedString = (opened ? "true" : "false");
  1271. String defaultCloseOperationString;
  1272. if (defaultCloseOperation == HIDE_ON_CLOSE) {
  1273. defaultCloseOperationString = "HIDE_ON_CLOSE";
  1274. } else if (defaultCloseOperation == DISPOSE_ON_CLOSE) {
  1275. defaultCloseOperationString = "DISPOSE_ON_CLOSE";
  1276. } else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) {
  1277. defaultCloseOperationString = "DO_NOTHING_ON_CLOSE";
  1278. } else if (defaultCloseOperation == 3) {
  1279. defaultCloseOperationString = "EXIT_ON_CLOSE";
  1280. } else defaultCloseOperationString = "";
  1281. return super.paramString() +
  1282. ",closable=" + closableString +
  1283. ",defaultCloseOperation=" + defaultCloseOperationString +
  1284. ",desktopIcon=" + desktopIconString +
  1285. ",frameIcon=" + frameIconString +
  1286. ",iconable=" + iconableString +
  1287. ",isClosed=" + isClosedString +
  1288. ",isIcon=" + isIconString +
  1289. ",isMaximum=" + isMaximumString +
  1290. ",isSelected=" + isSelectedString +
  1291. ",maximizable=" + maximizableString +
  1292. ",opened=" + openedString +
  1293. ",resizable=" + resizableString +
  1294. ",rootPane=" + rootPaneString +
  1295. ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString +
  1296. ",title=" + titleString;
  1297. }
  1298. // ======= begin optimized frame dragging defence code ==============
  1299. boolean isDragging = false;
  1300. boolean danger = false;
  1301. protected void paintComponent(Graphics g) {
  1302. if (isDragging) {
  1303. // System.out.println("ouch");
  1304. danger = true;
  1305. }
  1306. super.paintComponent(g);
  1307. }
  1308. // ======= end optimized frame dragging defence code ==============
  1309. /////////////////
  1310. // Accessibility support
  1311. ////////////////
  1312. /**
  1313. * Get the AccessibleContext associated with this JComponent
  1314. *
  1315. * @return the AccessibleContext of this JComponent
  1316. */
  1317. public AccessibleContext getAccessibleContext() {
  1318. if (accessibleContext == null) {
  1319. accessibleContext = new AccessibleJInternalFrame();
  1320. }
  1321. return accessibleContext;
  1322. }
  1323. /**
  1324. * The class used to obtain the accessible role for this object.
  1325. * <p>
  1326. * <strong>Warning:</strong>
  1327. * Serialized objects of this class will not be compatible with
  1328. * future Swing releases. The current serialization support is appropriate
  1329. * for short term storage or RMI between applications running the same
  1330. * version of Swing. A future release of Swing will provide support for
  1331. * long term persistence.
  1332. */
  1333. protected class AccessibleJInternalFrame extends AccessibleJComponent
  1334. implements AccessibleValue {
  1335. /**
  1336. * Get the accessible name of this object. This should almost never
  1337. * return java.awt.Component.getName(), as that generally isn't
  1338. * a localized name, and doesn't have meaning for the user. If the
  1339. * object is fundamentally a text object (e.g. a menu item), the
  1340. * accessible name should be the text of the object (e.g. "save").
  1341. * If the object has a tooltip, the tooltip text may also be an
  1342. * appropriate String to return.
  1343. *
  1344. * @return the localized name of the object -- can be null if this
  1345. * object does not have a name
  1346. * @see #setAccessibleName
  1347. */
  1348. public String getAccessibleName() {
  1349. if (accessibleName != null) {
  1350. return accessibleName;
  1351. } else {
  1352. return getTitle();
  1353. }
  1354. }
  1355. /**
  1356. * Get the role of this object.
  1357. *
  1358. * @return an instance of AccessibleRole describing the role of the
  1359. * object
  1360. * @see AccessibleRole
  1361. */
  1362. public AccessibleRole getAccessibleRole() {
  1363. return AccessibleRole.INTERNAL_FRAME;
  1364. }
  1365. /**
  1366. * Get the AccessibleValue associated with this object if one
  1367. * exists. Otherwise return null.
  1368. */
  1369. public AccessibleValue getAccessibleValue() {
  1370. return this;
  1371. }
  1372. //
  1373. // AccessibleValue methods
  1374. //
  1375. /**
  1376. * Get the value of this object as a Number.
  1377. *
  1378. * @return value of the object -- can be null if this object does not
  1379. * have a value
  1380. */
  1381. public Number getCurrentAccessibleValue() {
  1382. return new Integer(getLayer());
  1383. }
  1384. /**
  1385. * Set the value of this object as a Number.
  1386. *
  1387. * @return True if the value was set.
  1388. */
  1389. public boolean setCurrentAccessibleValue(Number n) {
  1390. if (n instanceof Integer) {
  1391. setLayer((Integer) n);
  1392. return true;
  1393. } else {
  1394. return false;
  1395. }
  1396. }
  1397. /**
  1398. * Get the minimum value of this object as a Number.
  1399. *
  1400. * @return Minimum value of the object; null if this object does not
  1401. * have a minimum value
  1402. */
  1403. public Number getMinimumAccessibleValue() {
  1404. return new Integer(Integer.MIN_VALUE);
  1405. }
  1406. /**
  1407. * Get the maximum value of this object as a Number.
  1408. *
  1409. * @return Maximum value of the object; null if this object does not
  1410. * have a maximum value
  1411. */
  1412. public Number getMaximumAccessibleValue() {
  1413. return new Integer(Integer.MAX_VALUE);
  1414. }
  1415. } // AccessibleJInternalFrame
  1416. /**
  1417. * This component represents an iconified version of a JInternalFrame.
  1418. * This API should NOT BE USED by Swing applications, as it will go
  1419. * away in future versions of Swing as its functionality is moved into
  1420. * JInternalFrame. This class is public only so that UI objects can
  1421. * display a desktop icon. If an application wants to display a
  1422. * desktop icon, it should create a JInternalFrame instance and
  1423. * iconify it.
  1424. * <p>
  1425. * <strong>Warning:</strong>
  1426. * Serialized objects of this class will not be compatible with
  1427. * future Swing releases. The current serialization support is appropriate
  1428. * for short term storage or RMI between applications running the same
  1429. * version of Swing. A future release of Swing will provide support for
  1430. * long term persistence.
  1431. *
  1432. * @author David Kloba
  1433. */
  1434. static public class JDesktopIcon extends JComponent implements Accessible
  1435. {
  1436. JInternalFrame internalFrame;
  1437. /** Create an icon for an internal frame
  1438. * @param f the JInternalFrame for which the icon is created
  1439. */
  1440. public JDesktopIcon(JInternalFrame f) {
  1441. setInternalFrame(f);
  1442. updateUI();
  1443. }
  1444. /**
  1445. * Returns the L&F object that renders this component.
  1446. *
  1447. * @return the DesktopIconUI object that renders this component
  1448. */
  1449. public DesktopIconUI getUI() {
  1450. return (DesktopIconUI)ui;
  1451. }
  1452. /**
  1453. * Sets the L&F object that renders this component.
  1454. *
  1455. * @param ui the DesktopIconUI L&F object
  1456. * @see UIDefaults#getUI
  1457. */
  1458. public void setUI(DesktopIconUI ui) {
  1459. super.setUI(ui);
  1460. }
  1461. /**
  1462. * Returns the JInternalFrame that this DesktopIcon is
  1463. * associated with.
  1464. * @return the JInternalFrame this icon is associated with
  1465. */
  1466. public JInternalFrame getInternalFrame() {
  1467. return internalFrame;
  1468. }
  1469. /**
  1470. * Sets the JInternalFrame that this DesktopIcon is
  1471. * associated with.
  1472. * @param f the JInternalFrame this icon is associated with
  1473. */
  1474. public void setInternalFrame(JInternalFrame f) {
  1475. internalFrame = f;
  1476. }
  1477. /** Convience method to ask the icon for the Desktop object
  1478. * it belongs to.
  1479. * @return the JDesktopPane that contains this icon's internal
  1480. * frame, or null if none found
  1481. */
  1482. public JDesktopPane getDesktopPane() {
  1483. if(getInternalFrame() != null)
  1484. return getInternalFrame().getDesktopPane();
  1485. return null;
  1486. }
  1487. /**
  1488. * Notification from the UIManager that the L&F has changed.
  1489. * Replaces the current UI object with the latest version from the
  1490. * UIManager.
  1491. *
  1492. * @see JComponent#updateUI
  1493. */
  1494. public void updateUI() {
  1495. boolean hadUI = (ui != null);
  1496. setUI((DesktopIconUI)UIManager.getUI(this));
  1497. invalidate();
  1498. Dimension r = getPreferredSize();
  1499. setSize(r.width, r.height);
  1500. if (internalFrame != null && internalFrame.getUI() != null) { // don't do this if UI not created yet
  1501. SwingUtilities.updateComponentTreeUI(internalFrame);
  1502. }
  1503. }
  1504. /* This method is called if updateUI was called on the associated
  1505. * JInternalFrame. It's necessary to avoid infinite recursion.
  1506. */
  1507. void updateUIWhenHidden() {
  1508. /* Update this UI and any associated internal frame */
  1509. setUI((DesktopIconUI)UIManager.getUI(this));
  1510. invalidate();
  1511. Component[] children = getComponents();
  1512. if (children != null) {
  1513. for(int i = 0; i < children.length; i++) {
  1514. SwingUtilities.updateComponentTreeUI(children[i]);
  1515. }
  1516. }
  1517. }
  1518. /**
  1519. * Returns the name of the L&F class that renders this component.
  1520. *
  1521. * @return "DesktopIconUI"
  1522. * @see JComponent#getUIClassID
  1523. * @see UIDefaults#getUI
  1524. */
  1525. public String getUIClassID() {
  1526. return "DesktopIconUI";
  1527. }
  1528. /////////////////
  1529. // Accessibility support
  1530. ////////////////
  1531. /**
  1532. * Get the AccessibleContext associated with this JComponent
  1533. *
  1534. * @return the AccessibleContext of this JComponent
  1535. */
  1536. public AccessibleContext getAccessibleContext() {
  1537. if (accessibleContext == null) {
  1538. accessibleContext = new AccessibleJDesktopIcon();
  1539. }
  1540. return accessibleContext;
  1541. }
  1542. /**
  1543. * The class used to obtain the accessible role for this object.
  1544. * <p>
  1545. * <strong>Warning:</strong>
  1546. * Serialized objects of this class will not be compatible with
  1547. * future Swing releases. The current serialization support is appropriate
  1548. * for short term storage or RMI between applications running the same
  1549. * version of Swing. A future release of Swing will provide support for
  1550. * long term persistence.
  1551. */
  1552. protected class AccessibleJDesktopIcon extends AccessibleJComponent
  1553. implements AccessibleValue {
  1554. /**
  1555. * Get the role of this object.
  1556. *
  1557. * @return an instance of AccessibleRole describing the role of the
  1558. * object
  1559. * @see AccessibleRole
  1560. */
  1561. public AccessibleRole getAccessibleRole() {
  1562. return AccessibleRole.DESKTOP_ICON;
  1563. }
  1564. /**
  1565. * Get the AccessibleValue associated with this object if one
  1566. * exists. Otherwise return null.
  1567. */
  1568. public AccessibleValue getAccessibleValue() {
  1569. return this;
  1570. }
  1571. //
  1572. // AccessibleValue methods
  1573. //
  1574. /**
  1575. * Get the value of this object as a Number.
  1576. *
  1577. * @return value of the object -- can be null if this object does not
  1578. * have a value
  1579. */
  1580. public Number getCurrentAccessibleValue() {
  1581. AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1582. AccessibleValue v = a.getAccessibleValue();
  1583. if (v != null) {
  1584. return v.getCurrentAccessibleValue();
  1585. } else {
  1586. return null;
  1587. }
  1588. }
  1589. /**
  1590. * Set the value of this object as a Number.
  1591. *
  1592. * @return True if the value was set.
  1593. */
  1594. public boolean setCurrentAccessibleValue(Number n) {
  1595. AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1596. AccessibleValue v = a.getAccessibleValue();
  1597. if (v != null) {
  1598. return v.setCurrentAccessibleValue(n);
  1599. } else {
  1600. return false;
  1601. }
  1602. }
  1603. /**
  1604. * Get the minimum value of this object as a Number.
  1605. *
  1606. * @return Minimum value of the object; null if this object does not
  1607. * have a minimum value
  1608. */
  1609. public Number getMinimumAccessibleValue() {
  1610. AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1611. if (a instanceof AccessibleValue) {
  1612. return ((AccessibleValue)a).getMinimumAccessibleValue();
  1613. } else {
  1614. return null;
  1615. }
  1616. }
  1617. /**
  1618. * Get the maximum value of this object as a Number.
  1619. *
  1620. * @return Maximum value of the object; null if this object does not
  1621. * have a maximum value
  1622. */
  1623. public Number getMaximumAccessibleValue() {
  1624. AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1625. if (a instanceof AccessibleValue) {
  1626. return ((AccessibleValue)a).getMaximumAccessibleValue();
  1627. } else {
  1628. return null;
  1629. }
  1630. }
  1631. } // AccessibleJDesktopIcon
  1632. }
  1633. }