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 34 import java.awt.event.ActionEvent; 35 import java.awt.event.KeyEvent; 36 37 import javax.swing.AbstractAction; 38 import javax.swing.ActionMap; 39 import javax.swing.InputMap; 40 import javax.swing.KeyStroke; 41 import javax.swing.JComponent; 42 import javax.swing.JLabel; 43 import javax.swing.JRootPane; 44 import javax.swing.SwingUtilities; 45 import javax.swing.UIManager; 46 import javax.swing.AbstractButton; 47 import javax.swing.JFrame; 48 import javax.swing.JMenu; 49 import javax.swing.JMenuBar; 50 import javax.swing.MenuElement; 51 import javax.swing.MenuSelectionManager; 52 53 import javax.swing.plaf.ActionMapUIResource; 54 import javax.swing.plaf.ComponentUI; 55 import javax.swing.plaf.InputMapUIResource; 56 57 import javax.swing.plaf.basic.BasicRootPaneUI; 58 import javax.swing.plaf.basic.ComboPopup; 59 60 /** 61 * Windows implementation of RootPaneUI, there is one shared between all 62 * JRootPane instances. 63 * 64 * @author Mark Davidson 65 * @since 1.4 66 */ 67 public class WindowsRootPaneUI extends BasicRootPaneUI { 68 69 private final static WindowsRootPaneUI windowsRootPaneUI = new WindowsRootPaneUI(); 70 static final AltProcessor altProcessor = new AltProcessor(); 71 72 public static ComponentUI createUI(JComponent c) { 73 return windowsRootPaneUI; 74 } 75 76 static class AltProcessor implements KeyEventPostProcessor { 77 static boolean altKeyPressed = false; 78 static boolean menuCanceledOnPress = false; 79 static JRootPane root = null; 80 static Window winAncestor = null; 81 82 void altPressed(KeyEvent ev) { 83 MenuSelectionManager msm = 84 MenuSelectionManager.defaultManager(); 85 MenuElement[] path = msm.getSelectedPath(); 86 if (path.length > 0 && ! (path[0] instanceof ComboPopup)) { 87 msm.clearSelectedPath(); 88 menuCanceledOnPress = true; 89 ev.consume(); 90 } else if(path.length > 0) { // We are in ComboBox 91 menuCanceledOnPress = false; 92 WindowsLookAndFeel.setMnemonicHidden(false); 93 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 94 ev.consume(); 95 } else { 96 menuCanceledOnPress = false; 97 WindowsLookAndFeel.setMnemonicHidden(false); 98 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 99 JMenuBar mbar = root != null ? root.getJMenuBar() : null; 100 if(mbar == null && winAncestor instanceof JFrame) { 101 mbar = ((JFrame)winAncestor).getJMenuBar(); 102 } 103 JMenu menu = mbar != null ? mbar.getMenu(0) : null; 104 if(menu != null) { 105 ev.consume(); 106 } 107 } 108 } 109 110 void altReleased(KeyEvent ev) { 111 if (menuCanceledOnPress) { 112 WindowsLookAndFeel.setMnemonicHidden(true); 113 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 114 return; 115 } 116 117 MenuSelectionManager msm = 118 MenuSelectionManager.defaultManager(); 119 if (msm.getSelectedPath().length == 0) { 120 // if no menu is active, we try activating the menubar 121 122 JMenuBar mbar = root != null ? root.getJMenuBar() : null; 123 if(mbar == null && winAncestor instanceof JFrame) { 124 mbar = ((JFrame)winAncestor).getJMenuBar(); 125 } 126 JMenu menu = mbar != null ? mbar.getMenu(0) : null; 127 128 if (menu != null) { 129 MenuElement[] path = new MenuElement[2]; 130 path[0] = mbar; 131 path[1] = menu; 132 msm.setSelectedPath(path); 133 } else if(!WindowsLookAndFeel.isMnemonicHidden()) { 134 WindowsLookAndFeel.setMnemonicHidden(true); 135 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 136 } 137 } else { 138 if((msm.getSelectedPath())[0] instanceof ComboPopup) { 139 WindowsLookAndFeel.setMnemonicHidden(true); 140 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 141 } 142 } 143 144 } 145 146 public boolean postProcessKeyEvent(KeyEvent ev) { 147 if(ev.isConsumed()) { 148 // do not manage consumed event 149 return false; 150 } 151 if (ev.getKeyCode() == KeyEvent.VK_ALT) { 152 root = SwingUtilities.getRootPane(ev.getComponent()); 153 winAncestor = (root == null ? null : 154 SwingUtilities.getWindowAncestor(root)); 155 156 if (ev.getID() == KeyEvent.KEY_PRESSED) { 157 if (!altKeyPressed) { 158 altPressed(ev); 159 } 160 altKeyPressed = true; 161 return true; 162 } else if (ev.getID() == KeyEvent.KEY_RELEASED) { 163 if (altKeyPressed) { 164 altReleased(ev); 165 } else { 166 MenuSelectionManager msm = 167 MenuSelectionManager.defaultManager(); 168 MenuElement[] path = msm.getSelectedPath(); 169 if (path.length <= 0) { 170 WindowsLookAndFeel.setMnemonicHidden(true); 171 WindowsGraphicsUtils.repaintMnemonicsInWindow(winAncestor); 172 } 173 } 174 altKeyPressed = false; 175 } 176 root = null; 177 winAncestor = null; 178 } else { 179 altKeyPressed = false; 180 } 181 return false; 182 } 183 } 184 }