Relates :
|
|
Relates :
|
|
Relates :
|
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 ----------
|