Skip to content

Commit a1302e5

Browse files
committed
8365625: Can't change accelerator colors in Windows L&F
Reviewed-by: psadhukhan, kizune
1 parent a1be297 commit a1302e5

File tree

5 files changed

+236
-57
lines changed

5 files changed

+236
-57
lines changed

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,20 @@ protected void paintBackground(Graphics g, JMenuItem menuItem,
7676
super.paintBackground(g, menuItem, bgColor);
7777
}
7878

79-
/**
80-
* Paint MenuItem.
81-
*/
79+
@Override
8280
protected void paintMenuItem(Graphics g, JComponent c,
8381
Icon checkIcon, Icon arrowIcon,
8482
Color background, Color foreground,
8583
int defaultTextIconGap) {
8684
if (WindowsMenuItemUI.isVistaPainting()) {
87-
WindowsMenuItemUI.paintMenuItem(accessor, g, c, checkIcon,
88-
arrowIcon, background, foreground,
89-
disabledForeground, acceleratorSelectionForeground,
90-
acceleratorForeground, defaultTextIconGap,
91-
menuItem, getPropertyPrefix());
85+
WindowsMenuItemUI.paintMenuItem(accessor, g, c,
86+
checkIcon, arrowIcon,
87+
background, foreground,
88+
disabledForeground,
89+
acceleratorSelectionForeground,
90+
acceleratorForeground,
91+
defaultTextIconGap,
92+
menuItem, getPropertyPrefix());
9293
return;
9394
}
9495
super.paintMenuItem(g, c, checkIcon, arrowIcon, background,

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

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,11 @@
2929
import java.awt.Font;
3030
import java.awt.FontMetrics;
3131
import java.awt.Graphics;
32-
import java.awt.Insets;
3332
import java.awt.Rectangle;
3433
import java.beans.PropertyChangeEvent;
3534
import java.beans.PropertyChangeListener;
36-
import java.util.Enumeration;
3735

38-
import javax.swing.AbstractButton;
39-
import javax.swing.ButtonGroup;
4036
import javax.swing.ButtonModel;
41-
import javax.swing.DefaultButtonModel;
4237
import javax.swing.Icon;
4338
import javax.swing.JComponent;
4439
import javax.swing.JMenu;
@@ -132,27 +127,6 @@ public void propertyChange(PropertyChangeEvent e) {
132127
menuItem.addPropertyChangeListener(changeListener);
133128
}
134129

135-
protected void installDefaults() {
136-
super.installDefaults();
137-
String prefix = getPropertyPrefix();
138-
139-
if (acceleratorSelectionForeground == null ||
140-
acceleratorSelectionForeground instanceof UIResource) {
141-
acceleratorSelectionForeground =
142-
UIManager.getColor(prefix + ".acceleratorSelectionForeground");
143-
}
144-
if (acceleratorForeground == null ||
145-
acceleratorForeground instanceof UIResource) {
146-
acceleratorForeground =
147-
UIManager.getColor(prefix + ".acceleratorForeground");
148-
}
149-
if (disabledForeground == null ||
150-
disabledForeground instanceof UIResource) {
151-
disabledForeground =
152-
UIManager.getColor(prefix + ".disabledForeground");
153-
}
154-
}
155-
156130
/**
157131
* {@inheritDoc}
158132
*/
@@ -165,15 +139,19 @@ protected void uninstallListeners() {
165139
changeListener = null;
166140
}
167141

142+
@Override
168143
protected void paintMenuItem(Graphics g, JComponent c,
169144
Icon checkIcon, Icon arrowIcon,
170145
Color background, Color foreground,
171146
int defaultTextIconGap) {
172147
if (WindowsMenuItemUI.isVistaPainting()) {
173-
WindowsMenuItemUI.paintMenuItem(accessor, g, c, checkIcon,
174-
arrowIcon, background, foreground,
175-
disabledForeground, acceleratorSelectionForeground,
176-
acceleratorForeground, defaultTextIconGap, menuItem,
148+
WindowsMenuItemUI.paintMenuItem(accessor, g, c,
149+
checkIcon, arrowIcon,
150+
background, foreground,
151+
disabledForeground,
152+
acceleratorSelectionForeground,
153+
acceleratorForeground,
154+
defaultTextIconGap, menuItem,
177155
getPropertyPrefix());
178156
return;
179157
}
@@ -182,12 +160,16 @@ protected void paintMenuItem(Graphics g, JComponent c,
182160
}
183161

184162
static void paintMenuItem(WindowsMenuItemUIAccessor accessor, Graphics g,
185-
JComponent c, Icon checkIcon, Icon arrowIcon,
163+
JComponent c,
164+
Icon checkIcon, Icon arrowIcon,
186165
Color background, Color foreground,
187166
Color disabledForeground,
188167
Color acceleratorSelectionForeground,
189168
Color acceleratorForeground,
190-
int defaultTextIconGap, JMenuItem menuItem, String prefix) {
169+
int defaultTextIconGap, JMenuItem menuItem,
170+
String prefix) {
171+
assert c == menuItem : "menuItem passed as 'c' must be the same";
172+
191173
// Save original graphics font and color
192174
Font holdf = g.getFont();
193175
Color holdc = g.getColor();

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

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,18 +131,20 @@ protected void installDefaults() {
131131
hotTrackingOn = (obj instanceof Boolean) ? (Boolean)obj : true;
132132
}
133133

134-
/**
135-
* Paint MenuItem.
136-
*/
134+
@Override
137135
protected void paintMenuItem(Graphics g, JComponent c,
138-
Icon checkIcon, Icon arrowIcon,
139-
Color background, Color foreground,
140-
int defaultTextIconGap) {
136+
Icon checkIcon, Icon arrowIcon,
137+
Color background, Color foreground,
138+
int defaultTextIconGap) {
139+
assert c == menuItem : "menuItem passed as 'c' must be the same";
141140
if (WindowsMenuItemUI.isVistaPainting()) {
142-
WindowsMenuItemUI.paintMenuItem(accessor, g, c, checkIcon, arrowIcon,
141+
WindowsMenuItemUI.paintMenuItem(accessor, g, c,
142+
checkIcon, arrowIcon,
143143
background, foreground,
144-
disabledForeground, acceleratorSelectionForeground,
145-
acceleratorForeground, defaultTextIconGap, menuItem,
144+
disabledForeground,
145+
acceleratorSelectionForeground,
146+
acceleratorForeground,
147+
defaultTextIconGap, menuItem,
146148
getPropertyPrefix());
147149
return;
148150
}

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,20 @@ protected void paintBackground(Graphics g, JMenuItem menuItem,
7676
super.paintBackground(g, menuItem, bgColor);
7777
}
7878

79-
/**
80-
* Paint MenuItem.
81-
*/
79+
@Override
8280
protected void paintMenuItem(Graphics g, JComponent c,
8381
Icon checkIcon, Icon arrowIcon,
8482
Color background, Color foreground,
8583
int defaultTextIconGap) {
8684
if (WindowsMenuItemUI.isVistaPainting()) {
87-
WindowsMenuItemUI.paintMenuItem(accessor, g, c, checkIcon,
88-
arrowIcon, background, foreground,
89-
disabledForeground, acceleratorSelectionForeground,
90-
acceleratorForeground, defaultTextIconGap,
91-
menuItem, getPropertyPrefix());
85+
WindowsMenuItemUI.paintMenuItem(accessor, g, c,
86+
checkIcon, arrowIcon,
87+
background, foreground,
88+
disabledForeground,
89+
acceleratorSelectionForeground,
90+
acceleratorForeground,
91+
defaultTextIconGap,
92+
menuItem, getPropertyPrefix());
9293
return;
9394
}
9495
super.paintMenuItem(g, c, checkIcon, arrowIcon, background,
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
* Copyright (c) 2025, 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+
import java.awt.BorderLayout;
25+
import java.awt.Color;
26+
import java.awt.event.InputEvent;
27+
import java.awt.event.KeyEvent;
28+
29+
import javax.swing.Box;
30+
import javax.swing.JFrame;
31+
import javax.swing.JLabel;
32+
import javax.swing.JMenu;
33+
import javax.swing.JMenuBar;
34+
import javax.swing.JMenuItem;
35+
import javax.swing.JPanel;
36+
import javax.swing.KeyStroke;
37+
import javax.swing.UIManager;
38+
39+
import static javax.swing.BorderFactory.createEmptyBorder;
40+
41+
/*
42+
* @test id=windows
43+
* @bug 8348760 8365375 8365389 8365625
44+
* @requires (os.family == "windows")
45+
* @summary Verify that Windows Look & Feel allows changing
46+
* accelerator colors
47+
* @library /java/awt/regtesthelpers
48+
* @build PassFailJFrame
49+
* @run main/manual MenuItemAcceleratorColor
50+
*/
51+
52+
/*
53+
* @test id=classic
54+
* @bug 8348760 8365375 8365389 8365625
55+
* @requires (os.family == "windows")
56+
* @summary Verify that Windows Classic Look & Feel allows changing
57+
* accelerator colors
58+
* @library /java/awt/regtesthelpers
59+
* @build PassFailJFrame
60+
* @run main/manual MenuItemAcceleratorColor classic
61+
*/
62+
public final class MenuItemAcceleratorColor {
63+
private static final String INSTRUCTIONS =
64+
"Click the Menu to open it.\n" +
65+
"\n" +
66+
"Verify that the first and the last menu items render " +
67+
"their accelerators using the default colors, the color " +
68+
"should match that of the menu item itself in regular and " +
69+
"selected states.\n" +
70+
"\n" +
71+
"Verify that the second menu item renders its accelerator " +
72+
"with green and that the color changes to red when selected.\n" +
73+
"\n" +
74+
"Verify that the third menu item renders its accelerator " +
75+
"with magenta and yellow correspondingly.\n" +
76+
"\n" +
77+
"Verify that only the fifth menu item renders its accelerator " +
78+
"with blue; both the fourth and sixth should render their " +
79+
"accelerator with a shade of gray.\n" +
80+
"\n" +
81+
"If the above conditions are satisfied, press the Pass button; " +
82+
"otherwise, press the Fail button.";
83+
84+
public static void main(String[] args) throws Exception {
85+
UIManager.setLookAndFeel((args.length > 0 && "classic".equals(args[0]))
86+
? "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel"
87+
: "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
88+
89+
PassFailJFrame.builder()
90+
.instructions(INSTRUCTIONS)
91+
.rows(20)
92+
.columns(60)
93+
.testUI(MenuItemAcceleratorColor::createUI)
94+
.build()
95+
.awaitAndCheck();
96+
}
97+
98+
private static Box createInfoPanel() {
99+
Box box = Box.createVerticalBox();
100+
box.add(new JLabel("Look and Feel: "
101+
+ UIManager.getLookAndFeel()
102+
.getName()));
103+
box.add(new JLabel("Java version: "
104+
+ System.getProperty("java.runtime.version")));
105+
return box;
106+
}
107+
108+
private static JFrame createUI() {
109+
JPanel content = new JPanel(new BorderLayout());
110+
content.setBorder(createEmptyBorder(8, 8, 8, 8));
111+
content.add(createInfoPanel(),
112+
BorderLayout.SOUTH);
113+
114+
JFrame frame = new JFrame("Accelerator colors in Windows L&F");
115+
frame.setJMenuBar(createMenuBar());
116+
frame.add(content, BorderLayout.CENTER);
117+
frame.setSize(350, 370);
118+
return frame;
119+
}
120+
121+
private static JMenuBar createMenuBar() {
122+
JMenuItem first = new JMenuItem("First menu item");
123+
first.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F,
124+
InputEvent.CTRL_DOWN_MASK));
125+
126+
// Modify colors for accelerator rendering
127+
Color acceleratorForeground = UIManager.getColor("MenuItem.acceleratorForeground");
128+
Color acceleratorSelectionForeground = UIManager.getColor("MenuItem.acceleratorSelectionForeground");
129+
UIManager.put("MenuItem.acceleratorForeground", Color.GREEN);
130+
UIManager.put("MenuItem.acceleratorSelectionForeground", Color.RED);
131+
132+
JMenuItem second = new JMenuItem("Second menu item");
133+
second.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
134+
InputEvent.SHIFT_DOWN_MASK
135+
| InputEvent.CTRL_DOWN_MASK));
136+
137+
UIManager.put("MenuItem.acceleratorForeground", Color.MAGENTA);
138+
UIManager.put("MenuItem.acceleratorSelectionForeground", Color.YELLOW);
139+
JMenuItem third = new JMenuItem("Third menu item");
140+
third.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,
141+
InputEvent.ALT_DOWN_MASK));
142+
143+
// Restore colors
144+
UIManager.put("MenuItem.acceleratorForeground", acceleratorForeground);
145+
UIManager.put("MenuItem.acceleratorSelectionForeground", acceleratorSelectionForeground);
146+
147+
148+
// Disabled foreground
149+
JMenuItem fourth = new JMenuItem("Fourth menu item");
150+
fourth.setEnabled(false);
151+
fourth.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F,
152+
InputEvent.CTRL_DOWN_MASK));
153+
154+
Color disabledForeground = UIManager.getColor("MenuItem.disabledForeground");
155+
UIManager.put("MenuItem.disabledForeground", Color.BLUE);
156+
157+
JMenuItem fifth = new JMenuItem("Fifth menu item");
158+
fifth.setEnabled(false);
159+
fifth.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F,
160+
InputEvent.CTRL_DOWN_MASK
161+
| InputEvent.SHIFT_DOWN_MASK));
162+
163+
// Restore disabled foreground
164+
UIManager.put("MenuItem.disabledForeground", disabledForeground);
165+
166+
JMenuItem sixth = new JMenuItem("Sixth menu item");
167+
sixth.setEnabled(false);
168+
sixth.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,
169+
InputEvent.CTRL_DOWN_MASK
170+
| InputEvent.ALT_DOWN_MASK));
171+
172+
173+
JMenuItem quit = new JMenuItem("Quit");
174+
quit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
175+
InputEvent.CTRL_DOWN_MASK));
176+
177+
JMenu menu = new JMenu("Menu");
178+
menu.add(first);
179+
menu.add(second);
180+
menu.add(third);
181+
menu.addSeparator();
182+
menu.add(fourth);
183+
menu.add(fifth);
184+
menu.add(sixth);
185+
menu.addSeparator();
186+
menu.add(quit);
187+
188+
JMenuBar menuBar = new JMenuBar();
189+
menuBar.add(menu);
190+
191+
return menuBar;
192+
}
193+
}

0 commit comments

Comments
 (0)