1 /* 2 * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.java.swing.plaf.windows; 27 28 import java.awt.Component; 29 import java.awt.Container; 30 import java.awt.Event; 31 import java.awt.KeyEventPostProcessor; 32 import java.awt.Window; 33 import java.awt.Toolkit; 34 import sun.awt.SunToolkit; 35 36 import java.awt.event.ActionEvent; 37 import java.awt.event.KeyEvent; 38 39 import javax.swing.AbstractAction; 40 import javax.swing.ActionMap; 41 import javax.swing.InputMap; 42 import javax.swing.KeyStroke; 43 import javax.swing.JComponent; 44 import javax.swing.JLabel; 45 import javax.swing.JRootPane; 46 import javax.swing.SwingUtilities; 47 import javax.swing.UIManager; 48 import javax.swing.AbstractButton; 49 import javax.swing.JFrame; 50 import javax.swing.JMenu; 51 import javax.swing.JMenuBar; 52 import javax.swing.MenuElement; 53 import javax.swing.MenuSelectionManager; 54 55 import javax.swing.plaf.ActionMapUIResource; 56 import javax.swing.plaf.ComponentUI; 57 import javax.swing.plaf.InputMapUIResource; 58 59 import javax.swing.plaf.basic.BasicRootPaneUI; 60 import javax.swing.plaf.basic.ComboPopup; 61 62 /** 63 * Windows implementation of RootPaneUI, there is one shared between all 64 * JRootPane instances. 65 * 66 * @author Mark Davidson 67 * @since 1.4 68 */ 69 public class WindowsRootPaneUI extends BasicRootPaneUI { 70 71 private final static WindowsRootPaneUI windowsRootPaneUI = new WindowsRootPaneUI(); 72 static final AltProcessor altProcessor = new AltProcessor(); 73 74 public static ComponentUI createUI(JComponent c) { 75 return windowsRootPaneUI; 76 } 77 78 static class AltProcessor implements KeyEventPostProcessor { 79 static boolean altKeyPressed = false; 80 static boolean menuCanceledOnPress = false; 81 static JRootPane root = null; 82 static Window winAncestor = null; 83 84 void altPressed(KeyEvent ev) { 85 MenuSelectionManager msm = 86 MenuSelectionManager.defaultManager(); 87 MenuElement[] path = msm.getSelectedPath(); 88 if (path.length > 0 && ! (path[0] instanceof ComboPopup)) { 89 msm.clearSelectedPath(); 90 menuCanceledOnPress = true; 91 ev.consume(); 92 } else if(path.length > 0) { // We are in ComboBox 93 menuCanceledOnPress = false; 94 WindowsLookAndFeel.setMnemonicHidden(false); 95 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 96 ev.consume(); 97 } else { 98 menuCanceledOnPress = false; 99 WindowsLookAndFeel.setMnemonicHidden(false); 100 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 101 JMenuBar mbar = root != null ? root.getJMenuBar() : null; 102 if(mbar == null && winAncestor instanceof JFrame) { 103 mbar = ((JFrame)winAncestor).getJMenuBar(); 104 } 105 JMenu menu = mbar != null ? mbar.getMenu(0) : null; 106 if(menu != null) { 107 ev.consume(); 108 } 109 } 110 } 111 112 void altReleased(KeyEvent ev) { 113 if (menuCanceledOnPress) { 114 WindowsLookAndFeel.setMnemonicHidden(true); 115 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 116 return; 117 } 118 119 MenuSelectionManager msm = 120 MenuSelectionManager.defaultManager(); 121 if (msm.getSelectedPath().length == 0) { 122 // if no menu is active, we try activating the menubar 123 124 JMenuBar mbar = root != null ? root.getJMenuBar() : null; 125 if(mbar == null && winAncestor instanceof JFrame) { 126 mbar = ((JFrame)winAncestor).getJMenuBar(); 127 } 128 JMenu menu = mbar != null ? mbar.getMenu(0) : null; 129 130 // Skip menu activation if the KeyEvent originated before 131 // the latest window deactivation. 132 boolean skip = false; 133 Toolkit tk = Toolkit.getDefaultToolkit(); 134 if (tk instanceof SunToolkit) { 135 skip = ev.getWhen() <= ((SunToolkit)tk).getDeactivationTime(winAncestor); 136 } 137 138 if (menu != null && !skip) { 139 MenuElement[] path = new MenuElement[2]; 140 path[0] = mbar; 141 path[1] = menu; 142 msm.setSelectedPath(path); 143 } else if(!WindowsLookAndFeel.isMnemonicHidden()) { 144 WindowsLookAndFeel.setMnemonicHidden(true); 145 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 146 } 147 } else { 148 if((msm.getSelectedPath())[0] instanceof ComboPopup) { 149 WindowsLookAndFeel.setMnemonicHidden(true); 150 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 151 } 152 } 153 154 } 155 156 public boolean postProcessKeyEvent(KeyEvent ev) { 157 if(ev.isConsumed()) { 158 // do not manage consumed event 159 return false; 160 } 161 if (ev.getKeyCode() == KeyEvent.VK_ALT) { 162 root = SwingUtilities.getRootPane(ev.getComponent()); 163 winAncestor = (root == null ? null : 164 SwingUtilities.getWindowAncestor(root)); 165 166 if (ev.getID() == KeyEvent.KEY_PRESSED) { 167 if (!altKeyPressed) { 168 altPressed(ev); 169 } 170 altKeyPressed = true; 171 return true; 172 } else if (ev.getID() == KeyEvent.KEY_RELEASED) { 173 if (altKeyPressed) { 174 altReleased(ev); 175 } else { 176 MenuSelectionManager msm = 177 MenuSelectionManager.defaultManager(); 178 MenuElement[] path = msm.getSelectedPath(); 179 if (path.length <= 0) { 180 WindowsLookAndFeel.setMnemonicHidden(true); 181 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 182 } 183 } 184 altKeyPressed = false; 185 } 186 root = null; 187 winAncestor = null; 188 } else { 189 altKeyPressed = false; 190 } 191 return false; 192 } 193 } 194 }