1. /*
  2. * @(#)WindowsRootPaneUI.java 1.10 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.windows;
  8. import java.awt.Component;
  9. import java.awt.Container;
  10. import java.awt.Event;
  11. import java.awt.KeyEventPostProcessor;
  12. import java.awt.Window;
  13. import java.awt.event.ActionEvent;
  14. import java.awt.event.KeyEvent;
  15. import javax.swing.AbstractAction;
  16. import javax.swing.ActionMap;
  17. import javax.swing.InputMap;
  18. import javax.swing.KeyStroke;
  19. import javax.swing.JComponent;
  20. import javax.swing.JRootPane;
  21. import javax.swing.SwingUtilities;
  22. import javax.swing.UIManager;
  23. import javax.swing.AbstractButton;
  24. import javax.swing.JFrame;
  25. import javax.swing.JMenu;
  26. import javax.swing.JMenuBar;
  27. import javax.swing.MenuElement;
  28. import javax.swing.MenuSelectionManager;
  29. import javax.swing.plaf.ActionMapUIResource;
  30. import javax.swing.plaf.ComponentUI;
  31. import javax.swing.plaf.InputMapUIResource;
  32. import javax.swing.plaf.basic.BasicRootPaneUI;
  33. import javax.swing.plaf.basic.ComboPopup;
  34. /**
  35. * Windows implementation of RootPaneUI, there is one shared between all
  36. * JRootPane instances.
  37. *
  38. * @version 1.10 01/23/03
  39. * @author Mark Davidson
  40. * @since 1.4
  41. */
  42. public class WindowsRootPaneUI extends BasicRootPaneUI {
  43. private final static WindowsRootPaneUI windowsRootPaneUI = new WindowsRootPaneUI();
  44. static final AltProcessor altProcessor = new AltProcessor();
  45. public static ComponentUI createUI(JComponent c) {
  46. return windowsRootPaneUI;
  47. }
  48. static class AltProcessor implements KeyEventPostProcessor {
  49. static boolean altKeyPressed = false;
  50. static boolean menuCanceledOnPress = false;
  51. static JRootPane root = null;
  52. static Window winAncestor = null;
  53. void repaintMnemonicsInWindow(Window w) {
  54. if(w == null || !w.isShowing()) {
  55. return;
  56. }
  57. Window[] ownedWindows = w.getOwnedWindows();
  58. for(int i=0;i<ownedWindows.length;i++) {
  59. repaintMnemonicsInWindow(ownedWindows[i]);
  60. }
  61. repaintMnemonicsInComponents(w.getComponents());
  62. }
  63. void repaintMnemonicsInComponents(Component[] c) {
  64. for(int i=0;i<c.length;i++) {
  65. if(c[i] instanceof AbstractButton
  66. && ((AbstractButton)c[i]).getMnemonic() != '\0') {
  67. c[i].repaint();
  68. continue;
  69. }
  70. if(c[i] instanceof Container) {
  71. repaintMnemonicsInComponents(
  72. ((Container)c[i]).getComponents());
  73. }
  74. }
  75. }
  76. void altPressed(KeyEvent ev) {
  77. MenuSelectionManager msm =
  78. MenuSelectionManager.defaultManager();
  79. MenuElement[] path = msm.getSelectedPath();
  80. if (path.length > 0 && ! (path[0] instanceof ComboPopup)) {
  81. msm.clearSelectedPath();
  82. menuCanceledOnPress = true;
  83. ev.consume();
  84. } else if(path.length > 0) { // We are in ComboBox
  85. menuCanceledOnPress = false;
  86. WindowsLookAndFeel.setMnemonicHidden(false);
  87. repaintMnemonicsInWindow(winAncestor);
  88. ev.consume();
  89. } else {
  90. menuCanceledOnPress = false;
  91. WindowsLookAndFeel.setMnemonicHidden(false);
  92. repaintMnemonicsInWindow(winAncestor);
  93. JMenuBar mbar = root != null ? root.getJMenuBar() : null;
  94. if(mbar == null && winAncestor instanceof JFrame) {
  95. mbar = ((JFrame)winAncestor).getJMenuBar();
  96. }
  97. JMenu menu = mbar != null ? mbar.getMenu(0) : null;
  98. if(menu != null) {
  99. ev.consume();
  100. }
  101. }
  102. }
  103. void altReleased(KeyEvent ev) {
  104. if (menuCanceledOnPress) {
  105. WindowsLookAndFeel.setMnemonicHidden(true);
  106. repaintMnemonicsInWindow(winAncestor);
  107. return;
  108. }
  109. MenuSelectionManager msm =
  110. MenuSelectionManager.defaultManager();
  111. if (msm.getSelectedPath().length == 0) {
  112. // if no menu is active, we try activating the menubar
  113. JMenuBar mbar = root != null ? root.getJMenuBar() : null;
  114. if(mbar == null && winAncestor instanceof JFrame) {
  115. mbar = ((JFrame)winAncestor).getJMenuBar();
  116. }
  117. JMenu menu = mbar != null ? mbar.getMenu(0) : null;
  118. if (menu != null) {
  119. MenuElement[] path = new MenuElement[2];
  120. path[0] = mbar;
  121. path[1] = menu;
  122. msm.setSelectedPath(path);
  123. } else if(!WindowsLookAndFeel.isMnemonicHidden()) {
  124. WindowsLookAndFeel.setMnemonicHidden(true);
  125. repaintMnemonicsInWindow(winAncestor);
  126. }
  127. } else {
  128. if((msm.getSelectedPath())[0] instanceof ComboPopup) {
  129. WindowsLookAndFeel.setMnemonicHidden(true);
  130. repaintMnemonicsInWindow(winAncestor);
  131. }
  132. }
  133. }
  134. public boolean postProcessKeyEvent(KeyEvent ev) {
  135. if (ev.getKeyCode() == KeyEvent.VK_ALT) {
  136. root = SwingUtilities.getRootPane(ev.getComponent());
  137. winAncestor = SwingUtilities.getWindowAncestor(root);
  138. if (ev.getID() == KeyEvent.KEY_PRESSED) {
  139. if (!altKeyPressed) {
  140. altPressed(ev);
  141. }
  142. altKeyPressed = true;
  143. return true;
  144. } else if (ev.getID() == KeyEvent.KEY_RELEASED) {
  145. if (altKeyPressed) {
  146. altReleased(ev);
  147. } else {
  148. MenuSelectionManager msm =
  149. MenuSelectionManager.defaultManager();
  150. MenuElement[] path = msm.getSelectedPath();
  151. if (path.length <= 0) {
  152. WindowsLookAndFeel.setMnemonicHidden(true);
  153. repaintMnemonicsInWindow(winAncestor);
  154. }
  155. }
  156. altKeyPressed = false;
  157. }
  158. } else {
  159. altKeyPressed = false;
  160. }
  161. return false;
  162. }
  163. }
  164. }