Skip to content

Commit 96bfe61

Browse files
author
Abhishek Kumar
committed
8326458: Menu mnemonics don't toggle in Windows LAF when F10 is pressed
Reviewed-by: psadhukhan, aivanov
1 parent fcf48ab commit 96bfe61

File tree

2 files changed

+143
-8
lines changed

2 files changed

+143
-8
lines changed

src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsMenuBarUI.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -139,19 +139,22 @@ protected void installKeyboardActions() {
139139
*/
140140
@SuppressWarnings("serial") // Superclass is not serializable across versions
141141
private static class TakeFocus extends AbstractAction {
142+
@Override
142143
public void actionPerformed(ActionEvent e) {
143144
JMenuBar menuBar = (JMenuBar)e.getSource();
144145
JMenu menu = menuBar.getMenu(0);
145146
if (menu != null) {
146147
MenuSelectionManager msm =
147148
MenuSelectionManager.defaultManager();
148-
MenuElement[] path = new MenuElement[2];
149-
path[0] = (MenuElement)menuBar;
150-
path[1] = (MenuElement)menu;
151-
msm.setSelectedPath(path);
152-
153-
// show mnemonics
154-
WindowsLookAndFeel.setMnemonicHidden(false);
149+
MenuElement[] selectedPath = msm.getSelectedPath();
150+
if (selectedPath.length > 0 && (selectedPath[0] instanceof JMenuBar)) {
151+
msm.clearSelectedPath();
152+
WindowsLookAndFeel.setMnemonicHidden(true);
153+
} else {
154+
MenuElement[] path = {menuBar, menu};
155+
msm.setSelectedPath(path);
156+
WindowsLookAndFeel.setMnemonicHidden(false);
157+
}
155158
WindowsLookAndFeel.repaintRootPane(menuBar);
156159
}
157160
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
* Copyright (c) 2024, 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.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8326458
27+
* @key headful
28+
* @requires (os.family == "windows")
29+
* @modules java.desktop/com.sun.java.swing.plaf.windows
30+
* @summary Verifies if menu mnemonics toggle on F10 press in Windows LAF
31+
* @run main TestMenuMnemonic
32+
*/
33+
34+
import java.awt.Robot;
35+
import java.awt.event.KeyEvent;
36+
import java.util.concurrent.atomic.AtomicInteger;
37+
import javax.swing.JFrame;
38+
import javax.swing.JMenu;
39+
import javax.swing.JMenuBar;
40+
import javax.swing.JMenuItem;
41+
import javax.swing.MenuElement;
42+
import javax.swing.MenuSelectionManager;
43+
import javax.swing.SwingUtilities;
44+
import javax.swing.UIManager;
45+
46+
import com.sun.java.swing.plaf.windows.WindowsLookAndFeel;
47+
48+
public class TestMenuMnemonic {
49+
50+
private static JFrame frame;
51+
private static JMenuBar menuBar;
52+
private static JMenu fileMenu;
53+
54+
private static final AtomicInteger mnemonicHideCount = new AtomicInteger(0);
55+
private static final AtomicInteger mnemonicShowCount = new AtomicInteger(0);
56+
57+
private static final int EXPECTED = 5;
58+
59+
public static void main(String[] args) throws Exception {
60+
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
61+
Robot robot = new Robot();
62+
robot.setAutoDelay(100);
63+
64+
try {
65+
SwingUtilities.invokeAndWait(TestMenuMnemonic::createAndShowUI);
66+
robot.waitForIdle();
67+
robot.delay(1000);
68+
69+
for (int i = 0; i < EXPECTED * 2; i++) {
70+
robot.keyPress(KeyEvent.VK_F10);
71+
robot.waitForIdle();
72+
robot.delay(50);
73+
robot.keyRelease(KeyEvent.VK_F10);
74+
robot.waitForIdle();
75+
robot.delay(50);
76+
SwingUtilities.invokeAndWait(TestMenuMnemonic::verifyMnemonicsState);
77+
}
78+
79+
if (mnemonicShowCount.get() != EXPECTED
80+
&& mnemonicHideCount.get() != EXPECTED) {
81+
throw new RuntimeException("Mismatch in Mnemonic show/hide on F10 press");
82+
}
83+
} finally {
84+
SwingUtilities.invokeAndWait(() -> {
85+
if (frame != null) {
86+
frame.dispose();
87+
}
88+
});
89+
}
90+
}
91+
92+
private static void verifyMnemonicsState() {
93+
MenuSelectionManager msm =
94+
MenuSelectionManager.defaultManager();
95+
MenuElement[] selectedPath = msm.getSelectedPath();
96+
if (WindowsLookAndFeel.isMnemonicHidden()) {
97+
mnemonicHideCount.getAndIncrement();
98+
// Check if selection is cleared when mnemonics are hidden
99+
if (selectedPath.length != 0) {
100+
throw new RuntimeException("Menubar is active after" +
101+
" mnemonics are hidden");
102+
}
103+
} else {
104+
mnemonicShowCount.getAndIncrement();
105+
if (selectedPath.length != 2
106+
&& (selectedPath[0] != menuBar || selectedPath[1] != fileMenu)) {
107+
throw new RuntimeException("No Menu and Menubar is active when" +
108+
" mnemonics are shown");
109+
}
110+
}
111+
}
112+
113+
private static void createAndShowUI() {
114+
frame = new JFrame("Test Menu Mnemonic Show/Hide");
115+
menuBar = new JMenuBar();
116+
fileMenu = new JMenu("File");
117+
JMenu editMenu = new JMenu("Edit");
118+
fileMenu.setMnemonic(KeyEvent.VK_F);
119+
editMenu.setMnemonic(KeyEvent.VK_E);
120+
JMenuItem item1 = new JMenuItem("Item 1");
121+
JMenuItem item2 = new JMenuItem("Item 2");
122+
fileMenu.add(item1);
123+
fileMenu.add(item2);
124+
menuBar.add(fileMenu);
125+
menuBar.add(editMenu);
126+
frame.setJMenuBar(menuBar);
127+
frame.setSize(250, 200);
128+
frame.setLocationRelativeTo(null);
129+
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
130+
frame.setVisible(true);
131+
}
132+
}

0 commit comments

Comments
 (0)