Excerpt from Oracle's KeyEvent source code:
//set from native code.
private transient long rawCode = 0;
private transient long primaryLevelUnicode = 0;
private transient long scancode = 0; // for MS Windows only
private transient long extendedKeyCode = 0;
First, I thought about parsing the KeyEvent's toString() return value because it contains the scancode. But then I wrote a utility method (Tried successfully on Windows 8.) that uses reflection:
final public static Integer getScancodeFromKeyEvent(final KeyEvent keyEvent) {
Integer ret;
Field field;
try {
field = KeyEvent.class.getDeclaredField("scancode");
} catch (NoSuchFieldException nsfe) {
System.err.println("ATTENTION! The KeyEvent object does not have a field named "scancode"! (Which is kinda weird.)");
nsfe.printStackTrace();
return null;
}
try {
field.setAccessible(true);
} catch (SecurityException se) {
System.err.println("ATTENTION! Changing the accessibility of the KeyEvent class' field "scancode" caused a security exception!");
se.printStackTrace();
return null;
}
try {
ret = (int) field.getLong(keyEvent);
} catch (IllegalAccessException iae) {
System.err.println("ATTENTION! It is not allowed to read the field "scancode" of the KeyEvent instance!");
iae.printStackTrace();
return null;
}
return ret;
}
Apparently, resetting the field's accessibility afterwards is not necessary, as I got an exception when using this method while the setAccessible() line was commented out. (I changed it on the fly back and forth and recompiled in IntelliJ while the runtime was still on. Should be the same in Eclipse.) Would be easily possible, though, using the isAccessible() method first.
I needed the scancode for playing music on the keyboard because changing the keyboard language between QWERTZ and QWERTY swapped the notes accordeonly. It's really sad that we don't have legal access to a scancode-like value. The above solution successfully ignored the current keyboard layout configuration.
By the way, toString return value for "z" and "y" with US keyboard layout:
[KEY_PRESSED,keyCode=90,keyText=Z,keyChar='z',keyLocation=KEY_LOCATION_STANDARD,rawCode=90,primaryLevelUnicode=122,scancode=44,extendedKeyCode=0x5a] on frame0]
[KEY_PRESSED,keyCode=89,keyText=Y,keyChar='y',keyLocation=KEY_LOCATION_STANDARD,rawCode=89,primaryLevelUnicode=121,scancode=21,extendedKeyCode=0x59] on frame0]
With DE keyboard layout:
[KEY_PRESSED,keyCode=89,keyText=Y,keyChar='y',keyLocation=KEY_LOCATION_STANDARD,rawCode=89,primaryLevelUnicode=121,scancode=44,extendedKeyCode=0x59] on frame0]
[KEY_PRESSED,keyCode=90,keyText=Z,keyChar='z',keyLocation=KEY_LOCATION_STANDARD,rawCode=90,primaryLevelUnicode=122,scancode=21,extendedKeyCode=0x5a] on frame0]
Mind the scancode.
As a bonus, off-topic:
[KEY_PRESSED,keyCode=10,keyText=Enter,keyChar=Enter,keyLocation=KEY_LOCATION_STANDARD,rawCode=13,primaryLevelUnicode=13,scancode=28,extendedKeyCode=0xa] on frame0]
[KEY_PRESSED,keyCode=10,keyText=Enter,keyChar=Enter,keyLocation=KEY_LOCATION_NUMPAD,rawCode=13,primaryLevelUnicode=13,scancode=28,extendedKeyCode=0xa] on frame0]
[KEY_PRESSED,keyCode=49,keyText=1,keyChar='1',keyLocation=KEY_LOCATION_STANDARD,rawCode=49,primaryLevelUnicode=49,scancode=2,extendedKeyCode=0x31] on frame0]
[KEY_PRESSED,keyCode=97,keyText=NumPad-1,keyChar='1',keyLocation=KEY_LOCATION_NUMPAD,rawCode=97,primaryLevelUnicode=49,scancode=79,extendedKeyCode=0x61] on frame0]