JDK-8139189 : VK_OEM_102 dead key detected as VK_UNDEFINED
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 6,7,8,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows
  • CPU: generic
  • Submitted: 2015-02-08
  • Updated: 2018-06-11
  • Resolved: 2016-06-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u152Fixed 9 b127Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

EXTRA RELEVANT SYSTEM CONFIGURATION :
Using a custom keyboard layout named Programmer Dvorak (http://www.kaufmann.no/roland/dvorak/). The key between left Shift and Z as the keys are called on a QWERTY layout (scancode 82 = 0x56) is translated to VK_OEM_102. This VK is then translated to a dead key 0x0004 (it's functionality is similar to that of the compose key). The character is EOT. I've also tried it (with the same result) with the 0x0002 key (STX).

A DESCRIPTION OF THE PROBLEM :
The key between left shift and Z (as they are called on a QWERTY layout) is not detected by Java when it is a dead key. This key works fine in most applications, but in Java applications, pushing it usually has no effect. I'm using a modified version of the Programmer Dvorak keyboard layout, but this is a problem with the "original" layout as well (version 1.2.4). 

When I switched the key to not be a dead key, but instead a '<' character, it worked as expected (When pressed, it would print the <. The unexpected thing was, that Java now saw it as VK_LESS).
When I changed the character mapping to 0x0002 (which I know worked correctly when used as a dead key located at AltGr+M), it did not get detected (it said VK_UNDEFINED).
Then I changed it's mapping to '<' in default position and 0x0002 in Shift position. It worked as expected in MS Notepad. In Java it didn't work as a dead key (Java saw 0x0 as the character) but worked as a < key.

Note: For debugging my test application I System.out.println'd the KeyEvents. I only saw these lines on my coding PC, not the one I used to test the keyboard layout (that requires lots of reboots). There I only tried it with the original (unmodified) Programmer Dvorak keyboard layout. Here is the relevant output line (I coldn't copy the control EOT character - here I replaced it with the text EOT):

java.awt.event.KeyEvent[KEY_PRESSED,keyCode=0,keyText=Unknown keyCode: 0x0,keyChar='EOT',keyLocation=KEY_LOCATION_STANDARD,rawCode=226,primaryLevelUnicode=4,scancode=86,extendedKeyCode=0x0] on javax.swing.JTable[,0,0,450x400,alignmentX=0.0,alignmentY=0.0,border=,flags=251658568,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_SUBSEQUENT_COLUMNS,cellSelectionEnabled=false,editingColumn=-1,editingRow=-1,gridColor=javax.swing.plaf.ColorUIResource[r=122,g=138,b=153],preferredViewportSize=java.awt.Dimension[width=450,height=400],rowHeight=16,rowMargin=1,rowSelectionAllowed=true,selectionBackground=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],selectionForeground=sun.swing.PrintColorUIResource[r=51,g=51,b=51],showHorizontalLines=true,showVerticalLines=true]

My conclusion: Java detects keys based on their primaryLevelUnicode, which is the character of the key in a non-modified position. It can detect dead control-character keys, but not in the OEM_102 position.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Install and enable the Programmer Dvorak keyboard layout (linked above).

Open a Java application with a JFrame that has this structure: JFrame->JPanel->JTextPane

Click into the text pane to start writing text.

Push the OEM_102 key (between LShift and Z on QWERTY keyboards).
Push the C key twice.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The '��' character being written. (U+010D)
ACTUAL -
The 'c' character written twice. (U+0063)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
package nulano.kblutil;

import javax.swing.*;
import java.awt.*;

public class InputBox {
	private JPanel panel1;
	private JTextPane typeTextHereTextPane;

	{
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
		$$$setupUI$$$();
	}

	/**
	 * Method generated by IntelliJ IDEA GUI Designer
	 * >>> IMPORTANT!! <<<
	 * DO NOT edit this method OR call it in your code!
	 *
	 * @noinspection ALL
	 */
	private void $$$setupUI$$$() {
		panel1 = new JPanel();
		panel1.setLayout(new BorderLayout(0, 0));
		typeTextHereTextPane = new JTextPane();
		typeTextHereTextPane.setText("Type text here...");
		panel1.add(typeTextHereTextPane, BorderLayout.CENTER);
	}

	public static void main(String[] args) {
		JFrame frame = new JFrame("Input Box");
		frame.setContentPane(new InputBox().panel1);
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.pack();
		frame.setVisible(true);
	}

}

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


Comments
OEM_102 in the Programmer Dvorak keyboard layuout is a compose (multi) key emulation on Windows by using chained dead keys. This does not work in java because AWT toolkit prematurely requests the character per each key press to provide it to the corresponding java.awt.event.KeyEvent and so breaks the compose dead key sequence.
17-05-2016

Moving to JDK project. Has a test case. Setting Fix/Version to JDK 9 for Dev evaluation. Will consider N-bp as needed.
08-10-2015

Could you please provide a detailed description how to install the keyboard layout required for the bug reproduction?
09-02-2015