1. /*
  2. * @(#)BasicDesktopPaneUI.java 1.55 04/05/18
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.plaf.basic;
  8. import javax.swing.*;
  9. import javax.swing.plaf.*;
  10. import java.beans.*;
  11. import java.awt.event.*;
  12. import java.awt.Dimension;
  13. import java.awt.Insets;
  14. import java.awt.Graphics;
  15. import java.awt.KeyboardFocusManager;
  16. import java.awt.*;
  17. import java.util.Vector;
  18. import sun.swing.DefaultLookup;
  19. import sun.swing.UIAction;
  20. /**
  21. * Basic L&F for a desktop.
  22. *
  23. * @version 1.55 05/18/04
  24. * @author Steve Wilson
  25. */
  26. public class BasicDesktopPaneUI extends DesktopPaneUI {
  27. // Old actions forward to an instance of this.
  28. private static final Actions SHARED_ACTION = new Actions();
  29. private static Dimension minSize = new Dimension(0,0);
  30. private static Dimension maxSize = new Dimension(Integer.MAX_VALUE,
  31. Integer.MAX_VALUE);
  32. private Handler handler;
  33. private PropertyChangeListener pcl;
  34. protected JDesktopPane desktop;
  35. protected DesktopManager desktopManager;
  36. /**
  37. * As of Java 2 platform v1.3 this previously undocumented field is no
  38. * longer used.
  39. * Key bindings are now defined by the LookAndFeel, please refer to
  40. * the key bindings specification for further details.
  41. *
  42. * @deprecated As of 1.3.
  43. */
  44. @Deprecated
  45. protected KeyStroke minimizeKey;
  46. /**
  47. * As of Java 2 platform v1.3 this previously undocumented field is no
  48. * longer used.
  49. * Key bindings are now defined by the LookAndFeel, please refer to
  50. * the key bindings specification for further details.
  51. *
  52. * @deprecated As of 1.3.
  53. */
  54. @Deprecated
  55. protected KeyStroke maximizeKey;
  56. /**
  57. * As of Java 2 platform v1.3 this previously undocumented field is no
  58. * longer used.
  59. * Key bindings are now defined by the LookAndFeel, please refer to
  60. * the key bindings specification for further details.
  61. *
  62. * @deprecated As of 1.3.
  63. */
  64. @Deprecated
  65. protected KeyStroke closeKey;
  66. /**
  67. * As of Java 2 platform v1.3 this previously undocumented field is no
  68. * longer used.
  69. * Key bindings are now defined by the LookAndFeel, please refer to
  70. * the key bindings specification for further details.
  71. *
  72. * @deprecated As of 1.3.
  73. */
  74. @Deprecated
  75. protected KeyStroke navigateKey;
  76. /**
  77. * As of Java 2 platform v1.3 this previously undocumented field is no
  78. * longer used.
  79. * Key bindings are now defined by the LookAndFeel, please refer to
  80. * the key bindings specification for further details.
  81. *
  82. * @deprecated As of 1.3.
  83. */
  84. @Deprecated
  85. protected KeyStroke navigateKey2;
  86. public static ComponentUI createUI(JComponent c) {
  87. return new BasicDesktopPaneUI();
  88. }
  89. public BasicDesktopPaneUI() {
  90. }
  91. public void installUI(JComponent c) {
  92. desktop = (JDesktopPane)c;
  93. installDefaults();
  94. installDesktopManager();
  95. installListeners();
  96. installKeyboardActions();
  97. }
  98. public void uninstallUI(JComponent c) {
  99. uninstallKeyboardActions();
  100. uninstallListeners();
  101. uninstallDesktopManager();
  102. uninstallDefaults();
  103. desktop = null;
  104. handler = null;
  105. }
  106. protected void installDefaults() {
  107. if (desktop.getBackground() == null ||
  108. desktop.getBackground() instanceof UIResource) {
  109. desktop.setBackground(UIManager.getColor("Desktop.background"));
  110. }
  111. LookAndFeel.installProperty(desktop, "opaque", Boolean.TRUE);
  112. }
  113. protected void uninstallDefaults() { }
  114. /**
  115. * Installs the <code>PropertyChangeListener</code> returned from
  116. * <code>createPropertyChangeListener</code> on the
  117. * <code>JDesktopPane</code>.
  118. *
  119. * @since 1.5
  120. * @see #createPropertyChangeListener
  121. */
  122. protected void installListeners() {
  123. pcl = createPropertyChangeListener();
  124. desktop.addPropertyChangeListener(pcl);
  125. }
  126. /**
  127. * Uninstalls the <code>PropertyChangeListener</code> returned from
  128. * <code>createPropertyChangeListener</code> from the
  129. * <code>JDesktopPane</code>.
  130. *
  131. * @since 1.5
  132. * @see #createPropertyChangeListener
  133. */
  134. protected void uninstallListeners() {
  135. desktop.removePropertyChangeListener(pcl);
  136. pcl = null;
  137. }
  138. protected void installDesktopManager() {
  139. desktopManager = desktop.getDesktopManager();
  140. if(desktopManager == null) {
  141. desktopManager = new BasicDesktopManager();
  142. desktop.setDesktopManager(desktopManager);
  143. }
  144. }
  145. protected void uninstallDesktopManager() {
  146. if(desktop.getDesktopManager() instanceof UIResource) {
  147. desktop.setDesktopManager(null);
  148. }
  149. desktopManager = null;
  150. }
  151. protected void installKeyboardActions(){
  152. InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
  153. if (inputMap != null) {
  154. SwingUtilities.replaceUIInputMap(desktop,
  155. JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
  156. }
  157. inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
  158. if (inputMap != null) {
  159. SwingUtilities.replaceUIInputMap(desktop,
  160. JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
  161. inputMap);
  162. }
  163. LazyActionMap.installLazyActionMap(desktop, BasicDesktopPaneUI.class,
  164. "DesktopPane.actionMap");
  165. registerKeyboardActions();
  166. }
  167. protected void registerKeyboardActions(){
  168. }
  169. protected void unregisterKeyboardActions(){
  170. }
  171. InputMap getInputMap(int condition) {
  172. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  173. return createInputMap(condition);
  174. }
  175. else if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
  176. return (InputMap)DefaultLookup.get(desktop, this,
  177. "Desktop.ancestorInputMap");
  178. }
  179. return null;
  180. }
  181. InputMap createInputMap(int condition) {
  182. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  183. Object[] bindings = (Object[])DefaultLookup.get(desktop,
  184. this, "Desktop.windowBindings");
  185. if (bindings != null) {
  186. return LookAndFeel.makeComponentInputMap(desktop, bindings);
  187. }
  188. }
  189. return null;
  190. }
  191. static void loadActionMap(LazyActionMap map) {
  192. map.put(new Actions(Actions.RESTORE));
  193. map.put(new Actions(Actions.CLOSE));
  194. map.put(new Actions(Actions.MOVE));
  195. map.put(new Actions(Actions.RESIZE));
  196. map.put(new Actions(Actions.LEFT));
  197. map.put(new Actions(Actions.SHRINK_LEFT));
  198. map.put(new Actions(Actions.RIGHT));
  199. map.put(new Actions(Actions.SHRINK_RIGHT));
  200. map.put(new Actions(Actions.UP));
  201. map.put(new Actions(Actions.SHRINK_UP));
  202. map.put(new Actions(Actions.DOWN));
  203. map.put(new Actions(Actions.SHRINK_DOWN));
  204. map.put(new Actions(Actions.ESCAPE));
  205. map.put(new Actions(Actions.MINIMIZE));
  206. map.put(new Actions(Actions.MAXIMIZE));
  207. map.put(new Actions(Actions.NEXT_FRAME));
  208. map.put(new Actions(Actions.PREVIOUS_FRAME));
  209. map.put(new Actions(Actions.NAVIGATE_NEXT));
  210. map.put(new Actions(Actions.NAVIGATE_PREVIOUS));
  211. }
  212. protected void uninstallKeyboardActions(){
  213. unregisterKeyboardActions();
  214. SwingUtilities.replaceUIInputMap(desktop, JComponent.
  215. WHEN_IN_FOCUSED_WINDOW, null);
  216. SwingUtilities.replaceUIInputMap(desktop, JComponent.
  217. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
  218. SwingUtilities.replaceUIActionMap(desktop, null);
  219. }
  220. public void paint(Graphics g, JComponent c) {}
  221. public Dimension getPreferredSize(JComponent c) {return null;}
  222. public Dimension getMinimumSize(JComponent c) {
  223. return minSize;
  224. }
  225. public Dimension getMaximumSize(JComponent c){
  226. return maxSize;
  227. }
  228. /**
  229. * Returns the <code>PropertyChangeListener</code> to install on
  230. * the <code>JDesktopPane</code>.
  231. *
  232. * @since 1.5
  233. * @return The PropertyChangeListener that will be added to track
  234. * changes in the desktop pane.
  235. */
  236. protected PropertyChangeListener createPropertyChangeListener() {
  237. return getHandler();
  238. }
  239. private Handler getHandler() {
  240. if (handler == null) {
  241. handler = new Handler();
  242. }
  243. return handler;
  244. }
  245. private class Handler implements PropertyChangeListener {
  246. public void propertyChange(PropertyChangeEvent evt) {
  247. String propertyName = evt.getPropertyName();
  248. if ("desktopManager" == propertyName) {
  249. installDesktopManager();
  250. }
  251. }
  252. }
  253. /**
  254. * The default DesktopManager installed by the UI.
  255. */
  256. private class BasicDesktopManager extends DefaultDesktopManager
  257. implements UIResource {
  258. }
  259. private static class Actions extends UIAction {
  260. private static String CLOSE = "close";
  261. private static String ESCAPE = "escape";
  262. private static String MAXIMIZE = "maximize";
  263. private static String MINIMIZE = "minimize";
  264. private static String MOVE = "move";
  265. private static String RESIZE = "resize";
  266. private static String RESTORE = "restore";
  267. private static String LEFT = "left";
  268. private static String RIGHT = "right";
  269. private static String UP = "up";
  270. private static String DOWN = "down";
  271. private static String SHRINK_LEFT = "shrinkLeft";
  272. private static String SHRINK_RIGHT = "shrinkRight";
  273. private static String SHRINK_UP = "shrinkUp";
  274. private static String SHRINK_DOWN = "shrinkDown";
  275. private static String NEXT_FRAME = "selectNextFrame";
  276. private static String PREVIOUS_FRAME = "selectPreviousFrame";
  277. private static String NAVIGATE_NEXT = "navigateNext";
  278. private static String NAVIGATE_PREVIOUS = "navigatePrevious";
  279. private final int MOVE_RESIZE_INCREMENT = 10;
  280. private static boolean moving = false;
  281. private static boolean resizing = false;
  282. private static JInternalFrame sourceFrame = null;
  283. private static Component focusOwner = null;
  284. Actions() {
  285. super(null);
  286. }
  287. Actions(String name) {
  288. super(name);
  289. }
  290. public void actionPerformed(ActionEvent e) {
  291. JDesktopPane dp = (JDesktopPane)e.getSource();
  292. String key = getName();
  293. if (CLOSE == key || MAXIMIZE == key || MINIMIZE == key ||
  294. RESTORE == key) {
  295. setState(dp, key);
  296. }
  297. else if (ESCAPE == key) {
  298. if (sourceFrame == dp.getSelectedFrame() &&
  299. focusOwner != null) {
  300. focusOwner.requestFocus();
  301. }
  302. moving = false;
  303. resizing = false;
  304. sourceFrame = null;
  305. focusOwner = null;
  306. }
  307. else if (MOVE == key || RESIZE == key) {
  308. sourceFrame = dp.getSelectedFrame();
  309. if (sourceFrame == null) {
  310. return;
  311. }
  312. moving = (key == MOVE) ? true : false;
  313. resizing = (key == RESIZE) ? true : false;
  314. focusOwner = KeyboardFocusManager.
  315. getCurrentKeyboardFocusManager().getFocusOwner();
  316. if (!SwingUtilities.isDescendingFrom(focusOwner, sourceFrame)) {
  317. focusOwner = null;
  318. }
  319. sourceFrame.requestFocus();
  320. }
  321. else if (LEFT == key ||
  322. RIGHT == key ||
  323. UP == key ||
  324. DOWN == key ||
  325. SHRINK_RIGHT == key ||
  326. SHRINK_LEFT == key ||
  327. SHRINK_UP == key ||
  328. SHRINK_DOWN == key) {
  329. JInternalFrame c = dp.getSelectedFrame();
  330. if (sourceFrame == null || c != sourceFrame ||
  331. KeyboardFocusManager.
  332. getCurrentKeyboardFocusManager().getFocusOwner() !=
  333. sourceFrame) {
  334. return;
  335. }
  336. Dimension size = c.getSize();
  337. Dimension minSize = c.getMinimumSize();
  338. Point loc = c.getLocation();
  339. if (LEFT == key) {
  340. if (moving) {
  341. c.setLocation(loc.x - MOVE_RESIZE_INCREMENT, loc.y);
  342. } else if (resizing) {
  343. c.setLocation(loc.x - MOVE_RESIZE_INCREMENT, loc.y);
  344. c.setSize(size.width + MOVE_RESIZE_INCREMENT,
  345. size.height);
  346. }
  347. } else if (RIGHT == key) {
  348. if (moving) {
  349. c.setLocation(loc.x + MOVE_RESIZE_INCREMENT, loc.y);
  350. } else if (resizing) {
  351. c.setLocation(loc.x, loc.y);
  352. c.setSize(size.width + MOVE_RESIZE_INCREMENT,
  353. size.height);
  354. }
  355. } else if (UP == key) {
  356. if (moving) {
  357. c.setLocation(loc.x, loc.y - MOVE_RESIZE_INCREMENT);
  358. } else if (resizing) {
  359. c.setLocation(loc.x, loc.y - MOVE_RESIZE_INCREMENT);
  360. c.setSize(size.width,
  361. size.height + MOVE_RESIZE_INCREMENT);
  362. }
  363. } else if (DOWN == key) {
  364. if (moving) {
  365. c.setLocation(loc.x, loc.y + MOVE_RESIZE_INCREMENT);
  366. } else if (resizing) {
  367. c.setLocation(loc.x, loc.y);
  368. c.setSize(size.width,
  369. size.height + MOVE_RESIZE_INCREMENT);
  370. }
  371. } else if (SHRINK_LEFT == key && resizing) {
  372. if (minSize.width < (size.width - MOVE_RESIZE_INCREMENT)) {
  373. c.setLocation(loc.x, loc.y);
  374. c.setSize(size.width - MOVE_RESIZE_INCREMENT,
  375. size.height);
  376. } else {
  377. c.setSize(minSize.width, size.height);
  378. }
  379. } else if (SHRINK_RIGHT == key && resizing) {
  380. if (minSize.width < (size.width - MOVE_RESIZE_INCREMENT)) {
  381. c.setLocation(loc.x + MOVE_RESIZE_INCREMENT, loc.y);
  382. c.setSize(size.width - MOVE_RESIZE_INCREMENT,
  383. size.height);
  384. } else {
  385. c.setLocation(loc.x - minSize.width + size.width,
  386. loc.y);
  387. c.setSize(minSize.width, size.height);
  388. }
  389. } else if (SHRINK_UP == key && resizing) {
  390. if (minSize.height <
  391. (size.height - MOVE_RESIZE_INCREMENT)) {
  392. c.setLocation(loc.x, loc.y);
  393. c.setSize(size.width,
  394. size.height - MOVE_RESIZE_INCREMENT);
  395. } else {
  396. c.setSize(size.width, minSize.height);
  397. }
  398. } else if (SHRINK_DOWN == key && resizing) {
  399. if (minSize.height <
  400. (size.height - MOVE_RESIZE_INCREMENT)) {
  401. c.setLocation(loc.x, loc.y + MOVE_RESIZE_INCREMENT);
  402. c.setSize(size.width,
  403. size.height - MOVE_RESIZE_INCREMENT);
  404. } else {
  405. c.setLocation(loc.x,
  406. loc.y - minSize.height + size.height);
  407. c.setSize(size.width, minSize.height);
  408. }
  409. }
  410. }
  411. else if (NEXT_FRAME == key || PREVIOUS_FRAME == key) {
  412. selectFrame(dp, (key == NEXT_FRAME) ? true : false);
  413. }
  414. else if (NAVIGATE_NEXT == key ||
  415. NAVIGATE_PREVIOUS == key) {
  416. boolean moveForward = true;
  417. if (NAVIGATE_PREVIOUS == key) {
  418. moveForward = false;
  419. }
  420. Container cycleRoot = dp.getFocusCycleRootAncestor();
  421. if (cycleRoot != null) {
  422. FocusTraversalPolicy policy =
  423. cycleRoot.getFocusTraversalPolicy();
  424. if (policy != null && policy instanceof
  425. SortingFocusTraversalPolicy) {
  426. SortingFocusTraversalPolicy sPolicy =
  427. (SortingFocusTraversalPolicy)policy;
  428. boolean idc = sPolicy.getImplicitDownCycleTraversal();
  429. try {
  430. sPolicy.setImplicitDownCycleTraversal(false);
  431. if (moveForward) {
  432. KeyboardFocusManager.
  433. getCurrentKeyboardFocusManager().
  434. focusNextComponent(dp);
  435. } else {
  436. KeyboardFocusManager.
  437. getCurrentKeyboardFocusManager().
  438. focusPreviousComponent(dp);
  439. }
  440. } finally {
  441. sPolicy.setImplicitDownCycleTraversal(idc);
  442. }
  443. }
  444. }
  445. }
  446. }
  447. private void selectFrame(JDesktopPane dp, boolean forward) {
  448. if (forward) {
  449. // navigate to the next frame
  450. int i = 0;
  451. verifyFramesCache(dp);
  452. if (framesCache.size() == 0) {
  453. return;
  454. }
  455. JInternalFrame f = dp.getSelectedFrame();
  456. if (f != null) {
  457. i = framesCache.indexOf(f);
  458. }
  459. if (i == -1) {
  460. /* if the frame is not there, its icon may be */
  461. i = framesCache.indexOf(f.getDesktopIcon());
  462. if (i == -1) {
  463. /* error */
  464. return;
  465. }
  466. }
  467. if (++i == framesCache.size()) {
  468. /* wrap */
  469. i = 0;
  470. }
  471. JComponent c = (JComponent) framesCache.elementAt(i);
  472. if (c instanceof JInternalFrame) {
  473. try {
  474. ((JInternalFrame)c).setSelected(true);
  475. dp.getDesktopManager().activateFrame((JInternalFrame)c);
  476. } catch (PropertyVetoException pve) {}
  477. } else {
  478. /* it had better be an icon! */
  479. if (!(c instanceof JInternalFrame.JDesktopIcon)){
  480. /* error */
  481. return;
  482. }
  483. try {
  484. ((JInternalFrame)((JInternalFrame.JDesktopIcon)c).
  485. getInternalFrame()).setSelected(true);
  486. dp.getDesktopManager().activateFrame(
  487. ((JInternalFrame.JDesktopIcon)c).
  488. getInternalFrame());
  489. } catch (PropertyVetoException pve) {}
  490. }
  491. } else {
  492. // navigate to the previous internal frame
  493. int i = 0;
  494. verifyFramesCache(dp);
  495. if (framesCache.size() == 0) {
  496. return;
  497. }
  498. JInternalFrame f = dp.getSelectedFrame();
  499. if (f != null) {
  500. i = framesCache.indexOf(f);
  501. }
  502. if (i == -1) {
  503. /* if the frame is not there, its icon may be */
  504. i = framesCache.indexOf(f.getDesktopIcon());
  505. if (i == -1) {
  506. /* error */
  507. return;
  508. }
  509. }
  510. if (--i == -1) {
  511. /* wrap */
  512. i = framesCache.size() - 1;
  513. }
  514. JComponent c = (JComponent) framesCache.elementAt(i);
  515. if (c instanceof JInternalFrame) {
  516. try {
  517. ((JInternalFrame)c).setSelected(true);
  518. } catch (PropertyVetoException pve) {}
  519. } else {
  520. /* it had better be an icon! */
  521. if (!(c instanceof JInternalFrame.JDesktopIcon)) {
  522. /* error */
  523. return;
  524. }
  525. try {
  526. ((JInternalFrame)((JInternalFrame.JDesktopIcon)c).
  527. getInternalFrame()).setSelected(true);
  528. } catch (PropertyVetoException pve) {}
  529. }
  530. }
  531. }
  532. private void setState(JDesktopPane dp, String state) {
  533. if (state == CLOSE) {
  534. JInternalFrame f = dp.getSelectedFrame();
  535. if (f == null) {
  536. return;
  537. }
  538. f.doDefaultCloseAction();
  539. } else if (state == MAXIMIZE) {
  540. // maximize the selected frame
  541. JInternalFrame f = dp.getSelectedFrame();
  542. if (f == null) {
  543. return;
  544. }
  545. if (!f.isMaximum()) {
  546. if (f.isIcon()) {
  547. try {
  548. f.setIcon(false);
  549. f.setMaximum(true);
  550. } catch (PropertyVetoException pve) {}
  551. } else {
  552. try {
  553. f.setMaximum(true);
  554. } catch (PropertyVetoException pve) {
  555. }
  556. }
  557. }
  558. } else if (state == MINIMIZE) {
  559. // minimize the selected frame
  560. JInternalFrame f = dp.getSelectedFrame();
  561. if (f == null) {
  562. return;
  563. }
  564. if (!f.isIcon()) {
  565. try {
  566. f.setIcon(true);
  567. } catch (PropertyVetoException pve) {
  568. }
  569. }
  570. } else if (state == RESTORE) {
  571. // restore the selected minimized or maximized frame
  572. JInternalFrame f = dp.getSelectedFrame();
  573. if (f == null) {
  574. return;
  575. }
  576. try {
  577. if (f.isIcon()) {
  578. f.setIcon(false);
  579. } else if (f.isMaximum()) {
  580. f.setMaximum(false);
  581. }
  582. f.setSelected(true);
  583. } catch (PropertyVetoException pve) {
  584. }
  585. }
  586. }
  587. public boolean isEnabled(Object sender) {
  588. if (sender instanceof JDesktopPane) {
  589. JDesktopPane dp = (JDesktopPane)sender;
  590. JInternalFrame iFrame = dp.getSelectedFrame();
  591. if (iFrame == null) {
  592. return false;
  593. }
  594. String action = getName();
  595. if (action == Actions.CLOSE) {
  596. return iFrame.isClosable();
  597. } else if (action == Actions.MINIMIZE) {
  598. return iFrame.isIconifiable();
  599. } else if (action == Actions.MAXIMIZE) {
  600. return iFrame.isMaximizable();
  601. }
  602. return true;
  603. }
  604. return false;
  605. }
  606. }
  607. private static Vector framesCache;
  608. /*
  609. * Handles restoring a minimized or maximized internal frame.
  610. */
  611. protected class OpenAction extends AbstractAction {
  612. public void actionPerformed(ActionEvent evt) {
  613. JDesktopPane dp = (JDesktopPane)evt.getSource();
  614. SHARED_ACTION.setState(dp, Actions.RESTORE);
  615. }
  616. public boolean isEnabled() {
  617. return true;
  618. }
  619. }
  620. /*
  621. * Handles closing an internal frame
  622. */
  623. protected class CloseAction extends AbstractAction {
  624. public void actionPerformed(ActionEvent evt) {
  625. JDesktopPane dp = (JDesktopPane)evt.getSource();
  626. SHARED_ACTION.setState(dp, Actions.CLOSE);
  627. }
  628. public boolean isEnabled() {
  629. JInternalFrame iFrame = desktop.getSelectedFrame();
  630. if (iFrame != null) {
  631. return iFrame.isClosable();
  632. }
  633. return false;
  634. }
  635. }
  636. /*
  637. * Handles minimizing an internal frame
  638. */
  639. protected class MinimizeAction extends AbstractAction {
  640. public void actionPerformed(ActionEvent evt) {
  641. JDesktopPane dp = (JDesktopPane)evt.getSource();
  642. SHARED_ACTION.setState(dp, Actions.MINIMIZE);
  643. }
  644. public boolean isEnabled() {
  645. JInternalFrame iFrame = desktop.getSelectedFrame();
  646. if (iFrame != null) {
  647. return iFrame.isIconifiable();
  648. }
  649. return false;
  650. }
  651. }
  652. /*
  653. * Handles maximizing an internal frame
  654. */
  655. protected class MaximizeAction extends AbstractAction {
  656. public void actionPerformed(ActionEvent evt) {
  657. JDesktopPane dp = (JDesktopPane)evt.getSource();
  658. SHARED_ACTION.setState(dp, Actions.MAXIMIZE);
  659. }
  660. public boolean isEnabled() {
  661. JInternalFrame iFrame = desktop.getSelectedFrame();
  662. if (iFrame != null) {
  663. return iFrame.isMaximizable();
  664. }
  665. return false;
  666. }
  667. }
  668. /*
  669. * Handles navigating to the next internal frame.
  670. */
  671. protected class NavigateAction extends AbstractAction {
  672. public void actionPerformed(ActionEvent evt) {
  673. JDesktopPane dp = (JDesktopPane)evt.getSource();
  674. SHARED_ACTION.selectFrame(dp, true);
  675. }
  676. public boolean isEnabled() {
  677. return true;
  678. }
  679. }
  680. private static void verifyFramesCache(JDesktopPane dp) {
  681. if (framesCache == null) {
  682. framesCache = new Vector();
  683. }
  684. // Check whether any internal frames have closed in
  685. // which case we have to refresh the frames cache.
  686. boolean framesHaveClosed = false;
  687. int len = framesCache.size();
  688. for (int i = 0; i < len; i++) {
  689. JComponent c =
  690. (JComponent)framesCache.elementAt(i);
  691. if (c instanceof JInternalFrame) {
  692. JInternalFrame f = (JInternalFrame)c;
  693. if (f.isClosed()) {
  694. framesHaveClosed = true;
  695. break;
  696. }
  697. }
  698. else if (c instanceof JInternalFrame.JDesktopIcon) {
  699. JInternalFrame.JDesktopIcon icon =
  700. (JInternalFrame.JDesktopIcon)c;
  701. JInternalFrame f = (JInternalFrame)icon.getInternalFrame();
  702. if (f.isClosed()) {
  703. framesHaveClosed = true;
  704. break;
  705. }
  706. }
  707. }
  708. JInternalFrame [] allFrames = dp.getAllFrames();
  709. if (framesHaveClosed || allFrames.length != framesCache.size()) {
  710. // Cache frames starting at the lowest layer.
  711. framesCache.clear();
  712. int low = dp.lowestLayer();
  713. int high = dp.highestLayer();
  714. for (int i = high; i >= low; i--) {
  715. Component [] comp = dp.getComponentsInLayer(i);
  716. if (comp.length > 0) {
  717. for (int j = 0; j < comp.length; j++) {
  718. framesCache.addElement(comp[j]);
  719. }
  720. }
  721. }
  722. }
  723. }
  724. }