-
Bug
-
Resolution: Duplicate
-
P3
-
None
-
1.3.0
-
generic
-
generic
Name: boT120536 Date: 01/29/2001
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
This is an intentional duplicate of 4133256 (JMenu.add(Action) should request
mnemonic AND accelerator from the Action object), which was incorrectly closed
as a duplicate of 4138691 (Action object could use a predefined ACCELERATOR_KEY
property).
The crux of the issue is the fact that JMenu.add() ignores a defined
accelerator. If you create an Action which specifies an accelerator, and then
add() the action to a JMenu, the created JMenuItem does not have an
accelerator. Despite the assertions of the individual who evaluated 4133256
(which was not submitted by me, incidentally), I consider this to be clearly
erroneous behavior, as it is both utterly stupid and requires the programmer to
come up with creative workarounds just to get a simple accelerator working
This issue should be reopened and resolved.
Test case demonstrating both broken behavior and workaround:
---- TestCase.java ----
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class TestCase {
static class ExitAction extends AbstractAction {
public ExitAction() {
super("Exit");
putValue(MNEMONIC_KEY, new Integer('x'));
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke('X',
KeyEvent.ALT_MASK));
}
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
public static void main(String[] arg) {
JFrame f = new JFrame("Demo");
Action exitAction = new ExitAction();
JMenuBar menubar = new JMenuBar();
JMenu menu = new JMenu("Broken");
menu.setMnemonic('B');
menu.add(exitAction);
// exitAction has a defined accelerator of Alt-X. The existing JMenu
implementation
// completely ignores this.
menubar.add(menu);
JMenu fixedMenu = new JMenu("Fixed") {
protected JMenuItem createActionComponent(Action action) {
JMenuItem result = super.createActionComponent(action);
result.setAccelerator((KeyStroke)
action.getValue(Action.ACCELERATOR_KEY));
// shouldn't have to subclass JMenu and override
createActionComponent to
// get it to pay attention to the accelerator, but I don't know
of a simpler
// way to do it (and even if a simpler workaround exists, it's
still a
// workaround...)
return result;
}
};
fixedMenu.setMnemonic('F');
fixedMenu.add(exitAction);
menubar.add(fixedMenu);
f.setJMenuBar(menubar);
JLabel text = new JLabel("<html><font color=\"black\">Both 'Broken' and
'Fixed' " +
"contain the exact same Action object.<br>" +
"'Broken' is a plain-vanilla JMenu object which
ignores the " +
"accelerator defined in the Action.<br>" +
"'Fixed' is an anonymous subclass of JMenu
which demonstrates " +
"both the correct behavior<br>" +
"and how to fix it.</font></html>");
text.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
text.setForeground(Color.black);
f.getContentPane().add(text);
f.pack();
Dimension screenSize = f.getToolkit().getScreenSize();
f.setLocation((screenSize.width - f.getWidth()) / 2,
(screenSize.height - f.getHeight()) / 2);
f.show();
}
}
(Review ID: 115978)
======================================================================
- duplicates
-
JDK-4304129 Action.ACCELERATOR_KEY and Action.MNEMONIC_KEY are not used by JMenuItem
-
- Resolved
-