JDK-6450018 : DefaultKeyboardFocusManager and component key binding
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2006-07-18
  • Updated: 2006-07-19
  • Resolved: 2006-07-19
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b91)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b91, mixed mode)

A DESCRIPTION OF THE PROBLEM :
Our customers are facing this problems from long time and it is worsen in jdk1.6
We have implemented shortcut keys using component key binding.  i.e. using actionmap and keymap
 I have a key binding on JPanel fo key   KeyEvent.VK_I and on this key I display  JTEXTFIELD on same JPANEL.
I also have a key binding on this same JPANEL for key KeyEvent.VK_ESCAPE and on this key I remove this JTEXTFIELD from JPANEL.
Now if you go on pressing  key  "i" and "escape" one by one for few times then sometimes suddenly  "i" is displayed inside JTextField.

I looked into this problem and found that when you press key "i" then three event are generated in sequence : KEY_PRESSED,KEY_TYPED,KEY_RELEASED for key  "i".

So I think sometimes  JTEXTFIELD gets displayed and after that KEY_TYPED event is fired, so I gets displayed inside JTEXTFIELD.



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
As "i" is shortcut key it should not get displayed. Also suppose if user types "iamol" very fast  on Japnel, then as "i" is used for keybinding action JTEXTFIELD should display "amol".

---------- BEGIN SOURCE ----------
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;

public class KeyTest3 {
	private final JFrame frame;
	private final JPanel framePanel;
	private final JLabel infoLabel;
	private final JTextField infoTextField;

	public KeyTest3(){
		frame = new JFrame("KeyTest3");
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		framePanel = new JPanel();
		infoLabel = new JLabel("press i .....");
		infoTextField = new JTextField(8);
		Container frameContainer = frame.getContentPane();
		
		InputMap keyMap = new InputMap();
		keyMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_I, 0), "insert");
		keyMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "escape");
		
		ActionMap actionMap = new ActionMap();
		actionMap.put("insert", new AbstractAction(){
			public void actionPerformed(ActionEvent e) {
				dataentryMode();
			}
		});
		
		actionMap.put("escape", new AbstractAction(){
			public void actionPerformed(ActionEvent e) {
				listMode();
			}
		});

		
		framePanel.setInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,keyMap);
		framePanel.setActionMap(actionMap);
		
		listMode();
		frameContainer.add(framePanel);
		frame.setSize(300,200);
		frame.setVisible(true);
		infoLabel.requestFocus();
	}
	
	public final void listMode(){
		framePanel.removeAll();
		framePanel.add(infoLabel);
		framePanel.revalidate();
		framePanel.repaint();
		infoLabel.requestFocus();
	}
	
	public final void dataentryMode() {
		try {
			Thread.sleep(200);
			framePanel.removeAll();
			framePanel.add(infoTextField);
			framePanel.revalidate();
			framePanel.repaint();
			infoTextField.requestFocus();
		}catch(InterruptedException iex){
			iex.printStackTrace();
		}
	}
	
	

	
	public static void main(String args[]) {
		new KeyTest3();
	}
	
	
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
I have done the changes in DefaultKeyBoardFocusManager.dispatchKeyEvent() wherein I ignore the KEY_TYPED event just after the shortcutkey action. But this workaround is very specific to my application. Can you suggest a better one ?