-
Bug
-
Resolution: Unresolved
-
P3
-
None
-
6, 6u2
-
Cause Known
-
x86
-
linux
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b104)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0-rc-b104, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux muellerp02linux 2.6.11.4-20a-smp #1 SMP Wed Mar 23 21:52:37 UTC 2005 x86_64 x86_64 x86_64 GNU/Linux
EXTRA RELEVANT SYSTEM CONFIGURATION :
This also happens on 32-bit Linux
A DESCRIPTION OF THE PROBLEM :
When a menu item is triggered via a mnemonic the corresponding character ends up appearing in the text component that had focus before the menu was activated. This only happens when the text component has a heavyweight ancestor other than the frame itself.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the attached HeavyMnemonicProblem class on Linux
2. Select the File menu
3. Invoke the Test menu item by pressing its mnemonic 't'.
4. Observe that the character 't' appears in the text area.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No character should appear in the text component as a result of triggering a menu item using its mnemonic
ACTUAL -
The mnemonic character both triggers the menu item and appears in the text component
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HeavyMnemonicProblem {
public static void main(String[] args) {
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
JFrame frame = new JFrame("Heavyweight/Mnemonic Problem");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Add a heavyweight panel containing a lightweigth MJTextArea to the frame's
// content pane.
Panel heavyPanel = new Panel(new BorderLayout());
JTextArea textArea = new JTextArea();
heavyPanel.add(textArea, BorderLayout.CENTER);
frame.getContentPane().add(heavyPanel);
// Add a menu bar with a mnemonic
JMenuBar bar = new JMenuBar();
JMenu menu = new JMenu("File");
menu.setMnemonic('F');
JMenuItem item = new JMenuItem("Test");
item.setMnemonic('T');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Test");
}
});
menu.add(item);
bar.add(menu);
frame.setJMenuBar(bar);
// Add an AWTEventListener for diagnostics
AWTEventListener awtListener = new AWTEventListener() {
public void eventDispatched(AWTEvent event) {
System.out.print(event.paramString());
System.out.println(" on " + event.getSource().getClass().getName());
}
};
Toolkit.getDefaultToolkit().addAWTEventListener(awtListener, AWTEvent.KEY_EVENT_MASK);
frame.setBounds(100, 100, 400, 300);
frame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The problem can be prevented by using a KeyEventDispatcher to detect and discard key typed events for a component other than the root pane when the preceeding key pressed event was on the root pane. The following code does this:
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new StrayKeyTypedSuppressor());
static class StrayKeyTypedSuppressor implements KeyEventDispatcher
{
private Component sPressedComponent;
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getID() == KeyEvent.KEY_PRESSED) {
if (event.getComponent() instanceof JRootPane)
sPressedComponent = event.getComponent();
} else {
if (event.getID() == KeyEvent.KEY_TYPED &&
sPressedComponent != null && sPressedComponent != event.getComponent())
return true;
sPressedComponent = null;
}
return false;
}
}
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b104)
Java HotSpot(TM) 64-Bit Server VM (build 1.6.0-rc-b104, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Linux muellerp02linux 2.6.11.4-20a-smp #1 SMP Wed Mar 23 21:52:37 UTC 2005 x86_64 x86_64 x86_64 GNU/Linux
EXTRA RELEVANT SYSTEM CONFIGURATION :
This also happens on 32-bit Linux
A DESCRIPTION OF THE PROBLEM :
When a menu item is triggered via a mnemonic the corresponding character ends up appearing in the text component that had focus before the menu was activated. This only happens when the text component has a heavyweight ancestor other than the frame itself.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the attached HeavyMnemonicProblem class on Linux
2. Select the File menu
3. Invoke the Test menu item by pressing its mnemonic 't'.
4. Observe that the character 't' appears in the text area.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No character should appear in the text component as a result of triggering a menu item using its mnemonic
ACTUAL -
The mnemonic character both triggers the menu item and appears in the text component
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class HeavyMnemonicProblem {
public static void main(String[] args) {
JPopupMenu.setDefaultLightWeightPopupEnabled(false);
JFrame frame = new JFrame("Heavyweight/Mnemonic Problem");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Add a heavyweight panel containing a lightweigth MJTextArea to the frame's
// content pane.
Panel heavyPanel = new Panel(new BorderLayout());
JTextArea textArea = new JTextArea();
heavyPanel.add(textArea, BorderLayout.CENTER);
frame.getContentPane().add(heavyPanel);
// Add a menu bar with a mnemonic
JMenuBar bar = new JMenuBar();
JMenu menu = new JMenu("File");
menu.setMnemonic('F');
JMenuItem item = new JMenuItem("Test");
item.setMnemonic('T');
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Test");
}
});
menu.add(item);
bar.add(menu);
frame.setJMenuBar(bar);
// Add an AWTEventListener for diagnostics
AWTEventListener awtListener = new AWTEventListener() {
public void eventDispatched(AWTEvent event) {
System.out.print(event.paramString());
System.out.println(" on " + event.getSource().getClass().getName());
}
};
Toolkit.getDefaultToolkit().addAWTEventListener(awtListener, AWTEvent.KEY_EVENT_MASK);
frame.setBounds(100, 100, 400, 300);
frame.setVisible(true);
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
The problem can be prevented by using a KeyEventDispatcher to detect and discard key typed events for a component other than the root pane when the preceeding key pressed event was on the root pane. The following code does this:
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new StrayKeyTypedSuppressor());
static class StrayKeyTypedSuppressor implements KeyEventDispatcher
{
private Component sPressedComponent;
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getID() == KeyEvent.KEY_PRESSED) {
if (event.getComponent() instanceof JRootPane)
sPressedComponent = event.getComponent();
} else {
if (event.getID() == KeyEvent.KEY_TYPED &&
sPressedComponent != null && sPressedComponent != event.getComponent())
return true;
sPressedComponent = null;
}
return false;
}
}
- duplicates
-
JDK-6622060 Unconsumed (or bad redirection of) mnemonic key event
- Closed
- relates to
-
JDK-6363026 Mnemonics don't consume proper events
- Resolved
-
JDK-6391688 Mnemonics typed into text field in dialog
- Resolved
-
JDK-6396785 REGRESSION: A component can get unexpected keyTyped event.
- Closed