JDK-4182247 : Invalid keyCodes in Windows punctuation KeyEvents
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1998-10-17
  • Updated: 2011-07-01
  • Resolved: 2011-07-01
Related Reports
Relates :  
Relates :  
Description
Name: eh37734			Date: 10/16/98


The following is a report that I compiled related
to KeyEvents on different platforms. This appears 
to be a very big obstacle to cross platform capability.
The programmer should not have to see which OS is
running in order to get consistent user input.

I have found a number of bugs that seem to describe
something close to the problems listed here. None 
of them seem to have a complete understanding of 
the problem though. I hope this test app help.

------

Differences between System Keyboards 8-6-98

WinNT system information:
Java 1.1.6: Sun Microsystems Inc.
java API version: 45.3
x86 Windows NT 4.0
Character encoding: 8859_1
Character encoding package: sun.io

Solaris system information:
Java 1.1.5: Sun Microsystems Inc.
java API version: 45.3
sparc Solaris 2.x
Character encoding: 8859_1
Character encoding package: sun.io

Columns on left were output on WinNT by KeyCodeTester.java. Comments on right compare the Solaris keyboard to these Windows keys.

event		char	code	text				comments
KeyPressed		122	F11				"stop" key on Solaris, not F11
KeyPressed		123	F12				"again" key on Solaris, not F12

				"printscrn" 		NOT reported on Solaris or Win
KeyPressed		145	Scroll Lock			NOT reported on Solaris
KeyPressed		19	Pause				NOT reported on Solaris

KeyPressed	-	189	Unknown keyCode: 0xbd	unknown code 0 on Solaris
KeyPressed	=	187	Unknown keyCode: 0xbb	known code 61 on Solaris

(see windows keys below for matching codes)
KeyPressed	[	219	Unknown keyCode: 0xdb	known code 91 on Solaris 
KeyPressed	\	220	Unknown keyCode: 0xdc	known code 92 on Solaris
KeyPressed	]	221	Unknown keyCode: 0xdd	known code 93 on Solaris
(Windows keys)
KeyPressed		91	[				left Windows key
KeyPressed		92	\				right Windows key
KeyPressed		93	]				property key

KeyPressed	;	186	Unknown keyCode: 0xba	known code 59 on Solaris
KeyPressed	,	188	Unknown keyCode: 0xbc	known code 44 on Solaris
KeyPressed	.	190	Unknown keyCode: 0xbe	known code 46 on Solaris
KeyPressed	/	191	Unknown keyCode: 0xbf	known code 47 on Solaris

(keypad 5)
KeyPressed		12	Clear				Not reported on Solaris 

Columns on left were output on Solaris by KeyCodeTester.java. These keys are unique to Solaris.
KeyPressed		156	Help
KeyPressed		157	Meta
KeyPressed		21	Kana

Other issues between  WinNT and Solaris.

Toggle keys (Caps Lock and Num Lock) on Solaris report a key pressed event when it is toggled on (light comes on) and a key released event when it is toggled off (light goes out). On the Windows side a key pressed event is reported when the key is pressed and a key released event is reported when the key is released. It does not matter if it is toggling the function on and off.

Also, The control keys (Ctrl, Alt, and Shift) are reported as down for key pressed, key typed, and key released events on Windows. On Solaris they are not reported as down for the key typed event.

On the Solaris the unlabeled key near the help key, props, undo, front, copy, open, paste, find, cut, F11, and F12 keys do not report events.

Macintosh system information:
Java 1.1.3: Apple Computer, Inc.
java API version: 45.3
Power PC Mac OS 8.1
Character encoding: MacTEC
Character encoding package: sun.io

Columns on left were output on WinNT by KeyCodeTester.java. Comments on right compare the Macintosh laptop keyboard to these Windows keys.

event		char	code	text				comments
KeyPressed	 	27	Escape			esc reported as clear (code 12) on mac
KeyPressed	 	8	Backspace			Labeled as "Delete" on Mac

KeyPressed	-	189	Unknown keyCode: 0x0	known code 109 "NumPad -" on Mac
KeyPressed	=	187	Unknown keyCode: 0xbb	known code 61 on Mac

(see windows keys below for matching codes)
KeyPressed	[	219	Unknown keyCode: 0xdb	known code 91 on Mac 
KeyPressed	\	220	Unknown keyCode: 0xdc	known code 92 on Mac
KeyPressed	]	221	Unknown keyCode: 0xdd	known code 93 on Mac
(Windows keys)
KeyPressed		91	[				left Windows key
KeyPressed		92	\				right Windows key
KeyPressed		93	]				properties key

KeyPressed	;	186	Unknown keyCode: 0xba	known code 59 on Mac
KeyPressed	,	188	Unknown keyCode: 0xbc	known code 44 on Mac
KeyPressed	.	190	Unknown keyCode: 0xbe	known code 46 on Mac
KeyPressed	/	191	Unknown keyCode: 0xbf	known code 47 on Mac

Other issues with the Mac.

On the Mac the Caps Lock, Shift, Ctrl, Option and Open Apple keys do not report events. They do on Windows (not Open Apple, obviously).

The problem here seems to be with the Windows operating system. It responds correctly to the improperly mapped key codes. The proper place to handle this is in the VM, not the KeyEvent.

The Code: KeyCodeTester.java

import com.sun.java.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * KeyCodeTester can be used to compare keyboard key codes from different Java
 * virtual machines
 */
public class KeyCodeTester extends java.awt.Frame
                           implements ActionListener,
                                      KeyListener,
                                      WindowListener
{
	Panel topPanel;
	TextField keyInput;
	TextArea output;
	Label label1;
	Button Clear;
	Checkbox allEvents;

	public KeyCodeTester()
	{
		setLayout(new BorderLayout());
		setVisible(false);
		setSize(600,340);
		topPanel = new Panel();
		label1 = new Label("   Type a key.");
		topPanel.add(label1);
		keyInput = new TextField();
		topPanel.add(keyInput);
		Clear = new Button();
		Clear.setLabel("Clear TextArea");
		topPanel.add(Clear);
		allEvents = new Checkbox("Report All Events");
		topPanel.add(allEvents);
		add(topPanel, BorderLayout.NORTH);
		output = new TextArea();
		add(output, BorderLayout.CENTER);
		setTitle("KeyCodeTester");

		keyInput.addKeyListener(this);
		Clear.addActionListener(this);
		this.addWindowListener(this);
	}

	static public void main(String args[])
	{
	    KeyCodeTester keyCodeTester = new KeyCodeTester();
		keyCodeTester.setVisible(true);
		keyCodeTester.getSystemInfo();
	}

    void getSystemInfo()
    {
   		output.appendText("Java " + System.getProperty("java.version") + ": "
            + System.getProperty("java.vendor") + "\n"
            + "java API version: " + System.getProperty("java.class.version") + "\n"
            + System.getProperty("os.arch") + " "
            + System.getProperty("os.name") + " "
            + System.getProperty("os.version") + "\n"
            + "Character encoding: " + System.getProperty("file.encoding") + "\n"
            + "Character encoding package: " + System.getProperty("file.encoding.pkg") + "\n");

        output.append("Event\t\tChar\tCode\tKey Code Text [Modifier Text]\n");
    }

	public void keyPressed(KeyEvent event)
	{
    	if (event.getSource() == keyInput)
    	{
            outputKeyInfo(event);

    		if(allEvents.getState() == false)
    		{
        		keyInput.setText("");
        	}
        }
	}

	public void keyTyped(KeyEvent event)
	{
	    if(allEvents.getState() == false)
	    {
    	    return;
    	}

		if (event.getSource() == keyInput)
		{
            outputKeyInfo(event);
        }
	}

	public void keyReleased(KeyEvent event)
	{
	    if(allEvents.getState() == false)
	    {
	        return;
	    }

		if (event.getSource() == keyInput)
		{
            outputKeyInfo(event);
       		keyInput.setText("");
    	}
	}
	
	void outputKeyInfo(KeyEvent event)
	{
	    char keyChar = event.getKeyChar();
	    int keyCode = event.getKeyCode();
	    String keyModifiersText = event.getKeyModifiersText(event.getModifiers());
        String eventText;
        switch(event.getID()) {
          case KeyEvent.KEY_PRESSED:
              eventText = "KEY_PRESSED";
              break;
          case KeyEvent.KEY_RELEASED:
              eventText = "KEY_RELEASED";
              break;
          case KeyEvent.KEY_TYPED:
              eventText = "KEY_TYPED";
              break;
          default:
              eventText = "unknown type";
        }

	    output.append(eventText + "\t");

	    if(event.isActionKey())
	    {
	        output.appendText("\t");
	    }
	    
	    if(keyChar == '\0' || keyChar == '\n')
	    {
	        output.appendText("\t");
	    }
	    else
	    {
	        output.appendText(keyChar + "\t");
	    }
		output.appendText(keyCode + "\t");
		output.appendText(event.getKeyText(keyCode));
		if(!keyModifiersText.equals(""))
		{
    		output.appendText(" [" + keyModifiersText + "]");
    	}
    	output.appendText("\n");
    }
    
	public void actionPerformed(ActionEvent event)
	{
		if (event.getSource() == Clear)
		{
    		output.setText("");
    		keyInput.setText("");
    		getSystemInfo();
    	}
	}

	public void windowClosing(WindowEvent event)
	{
		if (event.getSource() == KeyCodeTester.this)
        {
    		setVisible(false); // hide the Frame
    		dispose();	     // free the system resources
    		System.exit(0);    // close the application
    	}
	}

	public void windowOpened(WindowEvent event)
	{
	}

	public void windowClosed(WindowEvent event)
	{
	}

	public void windowIconified(WindowEvent event)
	{
	}

	public void windowDeiconified(WindowEvent event)
	{
	}

	public void windowActivated(WindowEvent event)
	{
	}

	public void windowDeactivated(WindowEvent event)
	{
	}
}
(Review ID: 36831)
======================================================================

Comments
EVALUATION Both 6275736 and 5036807 are fixed in JDK6/7, so I'm closing this report as not reproducible.
01-07-2011

EVALUATION According to ###@###.###, the Apple Command key is VK_META, and Option is VK_ALT. If they are not working, the submitter should probably contact Apple. eric.hawkes@eng 2001-03-09 Name: dmR10075 Date: 03/22/2004 I verified that: - On all platforms, different char-related keys(eg. ".", ",") generate the same key events, no events are missing - On Solaris, we generate exactly the same events in Java as we receive from X, and keycode/keychar is the same as xev reports. So, for example, the problem that "Again" generates F12 - it is a mapping problem, not Java problem, xev reports the same. - Open and Front don't generate any events - instead they perform some action to a window on a desktop, xev behaves in a similar fashion. - The only difference that I see remaining between Solaris and Windows is related to NumLock and CapsLock keys. On Solaris, their state goes along with the state of the led, while on Windows the events are unrelated to the state of the led. This is the behavior of the platform, but we can probably workaround this by generating missing events on Solaris. On Solaris, when I press NumLock, only KeyPress or KeyRelease arrives depending on a led status. Therefore, we can generate KEY_RELEASED when we process KeyPress for NumLock and KEY_PRESSED before we process KeyRelease. The same applies to CapsLock. We should check all other keys-with-led to make sure the implementation is consistent. However, this might introduce backward incompatibility - previously it was possible to track the state of NumLock by key events, now it will be impossible. We should probably add an API to track the state of such keys. ###@###.### 2004-03-22 ====================================================================== I'd like to comment on the note that "The programmer should not have to see which OS is running in order to get consistent user input." That's true but keyboard is not OS, and we perhaps should not attempt to hide a keyboard type. There are vendor keyboards, and we should (maybe) create dynamic mapping to return correctly at least vendor keys which we don't do now. See (6275736, 5036807). I suggest to fix and document these issues together in dolphin. ###@###.### 2005-06-23 09:08:38 GMT
23-06-2005

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mustang
07-09-2004