1. /*
  2. * @(#)BasicDesktopPaneUI.java 1.36 00/02/02
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing.plaf.basic;
  11. import javax.swing.*;
  12. import javax.swing.plaf.*;
  13. import java.beans.*;
  14. import java.awt.event.*;
  15. import java.awt.Dimension;
  16. import java.awt.Insets;
  17. import java.awt.Graphics;
  18. import java.awt.*;
  19. import java.util.Vector;
  20. /**
  21. * Basic L&F for a desktop.
  22. *
  23. * @version 1.36 02/02/00
  24. * @author Steve Wilson
  25. */
  26. public class BasicDesktopPaneUI extends DesktopPaneUI
  27. {
  28. private static Dimension minSize = new Dimension(0,0);
  29. private static Dimension maxSize = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  30. protected JDesktopPane desktop;
  31. protected DesktopManager desktopManager;
  32. /**
  33. * As of Java 2 platform v1.3 this previously undocumented field is no
  34. * longer used.
  35. * Key bindings are now defined by the LookAndFeel, please refer to
  36. * the key bindings specification for further details.
  37. *
  38. * @deprecated As of JDK version 1.3.
  39. */
  40. protected KeyStroke minimizeKey;
  41. /**
  42. * As of Java 2 platform v1.3 this previously undocumented field is no
  43. * longer used.
  44. * Key bindings are now defined by the LookAndFeel, please refer to
  45. * the key bindings specification for further details.
  46. *
  47. * @deprecated As of JDK version 1.3.
  48. */
  49. protected KeyStroke maximizeKey;
  50. /**
  51. * As of Java 2 platform v1.3 this previously undocumented field is no
  52. * longer used.
  53. * Key bindings are now defined by the LookAndFeel, please refer to
  54. * the key bindings specification for further details.
  55. *
  56. * @deprecated As of JDK version 1.3.
  57. */
  58. protected KeyStroke closeKey;
  59. /**
  60. * As of Java 2 platform v1.3 this previously undocumented field is no
  61. * longer used.
  62. * Key bindings are now defined by the LookAndFeel, please refer to
  63. * the key bindings specification for further details.
  64. *
  65. * @deprecated As of JDK version 1.3.
  66. */
  67. protected KeyStroke navigateKey;
  68. /**
  69. * As of Java 2 platform v1.3 this previously undocumented field is no
  70. * longer used.
  71. * Key bindings are now defined by the LookAndFeel, please refer to
  72. * the key bindings specification for further details.
  73. *
  74. * @deprecated As of JDK version 1.3.
  75. */
  76. protected KeyStroke navigateKey2;
  77. public static ComponentUI createUI(JComponent c) {
  78. return new BasicDesktopPaneUI();
  79. }
  80. public BasicDesktopPaneUI() {
  81. }
  82. public void installUI(JComponent c) {
  83. desktop = (JDesktopPane)c;
  84. installDefaults();
  85. installDesktopManager();
  86. installKeyboardActions();
  87. }
  88. public void uninstallUI(JComponent c) {
  89. uninstallKeyboardActions();
  90. uninstallDesktopManager();
  91. uninstallDefaults();
  92. desktop = null;
  93. }
  94. protected void installDefaults() {
  95. if (desktop.getBackground() == null ||
  96. desktop.getBackground() instanceof UIResource) {
  97. desktop.setBackground(UIManager.getColor("Desktop.background"));
  98. }
  99. }
  100. protected void uninstallDefaults() { }
  101. protected void installDesktopManager() {
  102. if(desktop.getDesktopManager() == null) {
  103. desktopManager = new DefaultDesktopManager();
  104. desktop.setDesktopManager(desktopManager);
  105. }
  106. }
  107. protected void uninstallDesktopManager() {
  108. if(desktop.getDesktopManager() == desktopManager) {
  109. desktop.setDesktopManager(null);
  110. }
  111. desktopManager = null;
  112. }
  113. protected void installKeyboardActions(){
  114. InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
  115. if (inputMap != null) {
  116. SwingUtilities.replaceUIInputMap(desktop,
  117. JComponent.WHEN_IN_FOCUSED_WINDOW, inputMap);
  118. }
  119. inputMap = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
  120. if (inputMap != null) {
  121. SwingUtilities.replaceUIInputMap(desktop,
  122. JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
  123. inputMap);
  124. }
  125. ActionMap actionMap = getActionMap();
  126. SwingUtilities.replaceUIActionMap(desktop, actionMap);
  127. registerKeyboardActions();
  128. }
  129. protected void registerKeyboardActions(){
  130. }
  131. protected void unregisterKeyboardActions(){
  132. }
  133. InputMap getInputMap(int condition) {
  134. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  135. return createInputMap(condition);
  136. }
  137. else if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
  138. return (InputMap)UIManager.get("Desktop.ancestorInputMap");
  139. }
  140. return null;
  141. }
  142. InputMap createInputMap(int condition) {
  143. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  144. Object[] bindings = (Object[])UIManager.get
  145. ("Desktop.windowBindings");
  146. if (bindings != null) {
  147. return LookAndFeel.makeComponentInputMap(desktop, bindings);
  148. }
  149. }
  150. return null;
  151. }
  152. ActionMap getActionMap() {
  153. return createActionMap();
  154. }
  155. ActionMap createActionMap() {
  156. ActionMap map = new ActionMapUIResource();
  157. map.put("restore", new OpenAction());
  158. map.put("close", new CloseAction());
  159. map.put("move", new MoveResizeAction("move"));
  160. map.put("resize", new MoveResizeAction("resize"));
  161. map.put("left", new MoveResizeAction("left"));
  162. map.put("right", new MoveResizeAction("right"));
  163. map.put("up", new MoveResizeAction("up"));
  164. map.put("down", new MoveResizeAction("down"));
  165. map.put("escape", new MoveResizeAction("escape"));
  166. map.put("minimize", new MinimizeAction());
  167. map.put("maximize", new MaximizeAction());
  168. map.put("selectNextFrame", nextAction = new NavigateAction());
  169. map.put("selectPreviousFrame", new PreviousAction());
  170. return map;
  171. }
  172. protected void uninstallKeyboardActions(){
  173. unregisterKeyboardActions();
  174. SwingUtilities.replaceUIInputMap(desktop, JComponent.
  175. WHEN_IN_FOCUSED_WINDOW, null);
  176. SwingUtilities.replaceUIInputMap(desktop, JComponent.
  177. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
  178. SwingUtilities.replaceUIActionMap(desktop, null);
  179. }
  180. public void paint(Graphics g, JComponent c) {}
  181. public Dimension getPreferredSize(JComponent c) {return null;}
  182. public Dimension getMinimumSize(JComponent c) {
  183. return minSize;
  184. }
  185. public Dimension getMaximumSize(JComponent c){
  186. return maxSize;
  187. }
  188. /*
  189. * Key binding for accessibility -----------------
  190. */
  191. private static Vector framesCache;
  192. private static int selectedIndex;
  193. private NavigateAction nextAction;
  194. private boolean moving = false;
  195. private boolean resizing = false;
  196. private final int MOVE_RESIZE_INCREMENT = 10;
  197. /*
  198. * Handles restoring a minimized or maximized internal frame.
  199. */
  200. protected class OpenAction extends AbstractAction {
  201. public void actionPerformed(ActionEvent e) {
  202. // restore the selected minimized or maximized frame
  203. verifyFramesCache();
  204. JComponent c =
  205. (JComponent)framesCache.elementAt(selectedIndex);
  206. if (c instanceof JInternalFrame) {
  207. JInternalFrame f = (JInternalFrame)c;
  208. try {
  209. if (f.isIcon()) {
  210. f.setIcon(false);
  211. } else if (f.isMaximum()) {
  212. f.setMaximum(false);
  213. }
  214. f.setSelected(true);
  215. desktopManager.activateFrame(f);
  216. } catch (PropertyVetoException pve) {
  217. }
  218. } else if (c instanceof JInternalFrame.JDesktopIcon) {
  219. JInternalFrame.JDesktopIcon icon =
  220. (JInternalFrame.JDesktopIcon)c;
  221. JInternalFrame f = (JInternalFrame)icon.getInternalFrame();
  222. try {
  223. f.setIcon(false);
  224. f.setSelected(true);
  225. desktopManager.activateFrame(f);
  226. } catch (PropertyVetoException pve) {
  227. }
  228. }
  229. }
  230. public boolean isEnabled() {
  231. return true;
  232. }
  233. }
  234. /*
  235. * Handles closing an internal frame
  236. */
  237. protected class CloseAction extends AbstractAction {
  238. public void actionPerformed(ActionEvent e) {
  239. verifyFramesCache();
  240. JComponent c =
  241. (JComponent)framesCache.elementAt(selectedIndex);
  242. if (c instanceof JInternalFrame) {
  243. JInternalFrame f = (JInternalFrame)c;
  244. if (f.isClosable()) {
  245. try {
  246. f.setClosed(true);
  247. nextAction.actionPerformed(e);
  248. } catch (PropertyVetoException pve) {
  249. }
  250. }
  251. }
  252. else if (c instanceof JInternalFrame.JDesktopIcon) {
  253. JInternalFrame.JDesktopIcon icon =
  254. (JInternalFrame.JDesktopIcon)c;
  255. JInternalFrame f = (JInternalFrame)icon.getInternalFrame();
  256. if (f.isClosable()) {
  257. try {
  258. f.setClosed(true);
  259. nextAction.actionPerformed(e);
  260. } catch (PropertyVetoException pve) {
  261. }
  262. }
  263. }
  264. }
  265. public boolean isEnabled() {
  266. return true;
  267. }
  268. }
  269. /*
  270. * Handles moving and resizing an internal frame
  271. */
  272. private class MoveResizeAction extends AbstractAction {
  273. private String command;
  274. public MoveResizeAction(String command) {
  275. this.command = command;
  276. }
  277. public void actionPerformed(ActionEvent e) {
  278. if ("move".equals(command)) {
  279. moving = true;
  280. resizing = false;
  281. return;
  282. } else if ("resize".equals(command)) {
  283. moving = false;
  284. resizing = true;
  285. return;
  286. } else if ("escape".equals(command)) {
  287. moving = resizing = false;
  288. return;
  289. }
  290. if (!moving && !resizing) {
  291. return;
  292. }
  293. JComponent c = desktop.getSelectedFrame();
  294. if ((c == null) || (!(c instanceof JInternalFrame))) {
  295. return;
  296. }
  297. Dimension size = c.getSize();
  298. Point loc = c.getLocation();
  299. if ("left".equals(command)) {
  300. if (moving) {
  301. c.setLocation(loc.x - MOVE_RESIZE_INCREMENT, loc.y);
  302. } else if (resizing) {
  303. c.setLocation(loc.x - MOVE_RESIZE_INCREMENT, loc.y);
  304. c.setSize(size.width + MOVE_RESIZE_INCREMENT, size.height);
  305. }
  306. } else if ("right".equals(command)) {
  307. if (moving) {
  308. c.setLocation(loc.x + MOVE_RESIZE_INCREMENT, loc.y);
  309. } else if (resizing) {
  310. c.setLocation(loc.x, loc.y);
  311. c.setSize(size.width + MOVE_RESIZE_INCREMENT, size.height);
  312. }
  313. } else if ("up".equals(command)) {
  314. if (moving) {
  315. c.setLocation(loc.x, loc.y - MOVE_RESIZE_INCREMENT);
  316. } else if (resizing) {
  317. c.setLocation(loc.x, loc.y - MOVE_RESIZE_INCREMENT);
  318. c.setSize(size.width, size.height + MOVE_RESIZE_INCREMENT);
  319. }
  320. } else if ("down".equals(command)) {
  321. if (moving) {
  322. c.setLocation(loc.x, loc.y + MOVE_RESIZE_INCREMENT);
  323. } else if (resizing) {
  324. c.setLocation(loc.x, loc.y);
  325. c.setSize(size.width, size.height + MOVE_RESIZE_INCREMENT);
  326. }
  327. }
  328. }
  329. public boolean isEnabled() {
  330. return true;
  331. }
  332. }
  333. /*
  334. * Handles minimizing an internal frame
  335. */
  336. protected class MinimizeAction extends AbstractAction {
  337. public void actionPerformed(ActionEvent e) {
  338. // minimize the selected frame
  339. verifyFramesCache();
  340. JComponent c =
  341. (JComponent)framesCache.elementAt(selectedIndex);
  342. if (c instanceof JInternalFrame) {
  343. JInternalFrame f = (JInternalFrame)c;
  344. if (f.isIconifiable()) {
  345. try {
  346. f.setIcon(true);
  347. nextAction.actionPerformed(e);
  348. } catch (PropertyVetoException pve) {
  349. }
  350. }
  351. }
  352. }
  353. public boolean isEnabled() {
  354. return true;
  355. }
  356. }
  357. /*
  358. * Handles maximizing an internal frame
  359. */
  360. protected class MaximizeAction extends AbstractAction {
  361. public void actionPerformed(ActionEvent e) {
  362. // maximize the selected frame
  363. verifyFramesCache();
  364. JComponent c =
  365. (JComponent)framesCache.elementAt(selectedIndex);
  366. if (c instanceof JInternalFrame) {
  367. JInternalFrame f = (JInternalFrame)c;
  368. if (f.isMaximizable()) {
  369. try {
  370. f.setMaximum(true);
  371. } catch (PropertyVetoException pve) {
  372. }
  373. }
  374. }
  375. else if (c instanceof JInternalFrame.JDesktopIcon) {
  376. JInternalFrame.JDesktopIcon icon =
  377. (JInternalFrame.JDesktopIcon)c;
  378. JInternalFrame f = (JInternalFrame)icon.getInternalFrame();
  379. if (f.isMaximizable()) {
  380. try {
  381. f.setIcon(false);
  382. f.setMaximum(true);
  383. } catch (PropertyVetoException pve) {
  384. }
  385. }
  386. }
  387. }
  388. public boolean isEnabled() {
  389. return true;
  390. }
  391. }
  392. /*
  393. * Handles navigating to the next internal frame.
  394. */
  395. protected class NavigateAction extends AbstractAction {
  396. public void actionPerformed(ActionEvent e) {
  397. // navigate to the next frame
  398. verifyFramesCache();
  399. selectedIndex++;
  400. if (selectedIndex >= framesCache.size()) {
  401. selectedIndex = 0;
  402. }
  403. JComponent c =
  404. (JComponent)framesCache.elementAt(selectedIndex);
  405. if (c instanceof JInternalFrame) {
  406. JInternalFrame f = (JInternalFrame)c;
  407. try {
  408. f.setSelected(true);
  409. desktopManager.activateFrame(f);
  410. } catch (PropertyVetoException pve) {
  411. }
  412. }
  413. else if (c instanceof JInternalFrame.JDesktopIcon) {
  414. JInternalFrame.JDesktopIcon icon =
  415. (JInternalFrame.JDesktopIcon)c;
  416. JInternalFrame f = (JInternalFrame)icon.getInternalFrame();
  417. try {
  418. f.setSelected(true);
  419. desktopManager.activateFrame(f);
  420. } catch (PropertyVetoException pve) {
  421. }
  422. }
  423. }
  424. public boolean isEnabled() {
  425. return true;
  426. }
  427. }
  428. /*
  429. * Handles navigating to the previous internal frame.
  430. */
  431. private class PreviousAction extends AbstractAction {
  432. public void actionPerformed(ActionEvent e) {
  433. // navigate to the previous internal frame
  434. verifyFramesCache();
  435. selectedIndex--;
  436. if (selectedIndex < 0) {
  437. selectedIndex = framesCache.size() - 1;
  438. }
  439. JComponent c =
  440. (JComponent)framesCache.elementAt(selectedIndex);
  441. if (c instanceof JInternalFrame) {
  442. JInternalFrame f = (JInternalFrame)c;
  443. try {
  444. f.setSelected(true);
  445. desktopManager.activateFrame(f);
  446. } catch (PropertyVetoException pve) {
  447. }
  448. }
  449. else if (c instanceof JInternalFrame.JDesktopIcon) {
  450. JInternalFrame.JDesktopIcon icon =
  451. (JInternalFrame.JDesktopIcon)c;
  452. JInternalFrame f = (JInternalFrame)icon.getInternalFrame();
  453. try {
  454. f.setSelected(true);
  455. desktopManager.activateFrame(f);
  456. } catch (PropertyVetoException pve) {
  457. }
  458. }
  459. }
  460. public boolean isEnabled() {
  461. return true;
  462. }
  463. }
  464. /*
  465. * Verifies the internal frames cache is up to date.
  466. */
  467. private void verifyFramesCache() {
  468. // Need to initialize?
  469. boolean shouldSetSelection = false;
  470. if (framesCache == null) {
  471. framesCache = new Vector();
  472. shouldSetSelection = true;
  473. }
  474. // Check whether any internal frames have closed in
  475. // which case we have to refresh the frames cache.
  476. boolean framesHaveClosed = false;
  477. int len = framesCache.size();
  478. for (int i = 0; i < len; i++) {
  479. JComponent c =
  480. (JComponent)framesCache.elementAt(i);
  481. if (c instanceof JInternalFrame) {
  482. JInternalFrame f = (JInternalFrame)c;
  483. if (f.isClosed()) {
  484. framesHaveClosed = true;
  485. break;
  486. }
  487. }
  488. else if (c instanceof JInternalFrame.JDesktopIcon) {
  489. JInternalFrame.JDesktopIcon icon =
  490. (JInternalFrame.JDesktopIcon)c;
  491. JInternalFrame f = (JInternalFrame)icon.getInternalFrame();
  492. if (f.isClosed()) {
  493. framesHaveClosed = true;
  494. break;
  495. }
  496. }
  497. }
  498. JInternalFrame [] allFrames = desktop.getAllFrames();
  499. if (framesHaveClosed || allFrames.length != framesCache.size()) {
  500. // Cache frames starting at the lowest layer.
  501. framesCache.clear();
  502. int low = desktop.lowestLayer();
  503. int high = desktop.highestLayer();
  504. int index = 0;
  505. for (int i = high; i >= low; i--) {
  506. Component [] comp = desktop.getComponentsInLayer(i);
  507. if (comp.length > 0) {
  508. for (int j = 0; j < comp.length; j++) {
  509. framesCache.addElement(comp[j]);
  510. if (shouldSetSelection &&
  511. comp[j] instanceof JInternalFrame) {
  512. if (((JInternalFrame)comp[j]).isSelected()) {
  513. selectedIndex = index;
  514. }
  515. }
  516. index++;
  517. }
  518. }
  519. }
  520. }
  521. }
  522. // End of accessibility keybindings
  523. }