Java 中键盘事件的奇怪行为
当我按下键盘上的“删除”按钮时,程序会收到三个事件 - KEY_PRESSED
、KEY_TYPED
和 KEY_RELEASED
。问题是,在KEY_PRESSED
和KEY_RELEASED
中,设置了参数“keyCode”
,但在KEY_TYPED
中它是不是(事实上,该事件中没有任何有意义的信息)。使用F5
键,它甚至更有趣 - KEY_PRESSED
和KEY_RELEASED
被注册,但KEY_TYPED
永远不会发生。
侦听器是通过 Toolkit.getDefaultToolkit().addAWTEventListener() 添加的。使用 JDK 6.26。
我的问题可能是什么?
编辑: 以下是按下 Delete
键时发生的事件:
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=127,keyText=Delete,keyChar=Delete,keyLocation=KEY_LOCATION_STANDARD,rawCode=119,primaryLevelUnicode=127,scancode=0] on javax.swing.JButton[,0,0,61x30,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.synth.SynthBorder@50f38cf0,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon@6ae2d0b2,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=SVG,defaultCapable=false]
java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyText=Unknown keyCode: 0x0,keyChar=Delete,keyLocation=KEY_LOCATION_UNKNOWN,rawCode=0,primaryLevelUnicode=127,scancode=0] on javax.swing.JButton[,0,0,61x30,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.synth.SynthBorder@50f38cf0,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon@6ae2d0b2,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=SVG,defaultCapable=false]
java.awt.event.KeyEvent[KEY_RELEASED,keyCode=127,keyText=Delete,keyChar=Delete,keyLocation=KEY_LOCATION_STANDARD,rawCode=119,primaryLevelUnicode=127,scancode=0] on javax.swing.JButton[,0,0,61x30,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.synth.SynthBorder@50f38cf0,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon@6ae2d0b2,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=SVG,defaultCapable=false]
When I press "Delete"
button on the keyboard, program gets three events - KEY_PRESSED
, KEY_TYPED
, and KEY_RELEASED
. The problem is, in KEY_PRESSED
and KEY_RELEASED
, parameter "keyCode"
is set, but in the KEY_TYPED
it is not (in fact, there no meaningful info in that event). With F5
key, it is even funnier - KEY_PRESSED
and KEY_RELEASED
are registered, but KEY_TYPED
never occurs.
The listener was added via Toolkit.getDefaultToolkit().addAWTEventListener()
. Using JDK 6.26.
What could be my problem?
EDIT:
Here are the events that happen when Delete
key is pressed:
java.awt.event.KeyEvent[KEY_PRESSED,keyCode=127,keyText=Delete,keyChar=Delete,keyLocation=KEY_LOCATION_STANDARD,rawCode=119,primaryLevelUnicode=127,scancode=0] on javax.swing.JButton[,0,0,61x30,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.synth.SynthBorder@50f38cf0,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon@6ae2d0b2,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=SVG,defaultCapable=false]
java.awt.event.KeyEvent[KEY_TYPED,keyCode=0,keyText=Unknown keyCode: 0x0,keyChar=Delete,keyLocation=KEY_LOCATION_UNKNOWN,rawCode=0,primaryLevelUnicode=127,scancode=0] on javax.swing.JButton[,0,0,61x30,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.synth.SynthBorder@50f38cf0,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon@6ae2d0b2,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=SVG,defaultCapable=false]
java.awt.event.KeyEvent[KEY_RELEASED,keyCode=127,keyText=Delete,keyChar=Delete,keyLocation=KEY_LOCATION_STANDARD,rawCode=119,primaryLevelUnicode=127,scancode=0] on javax.swing.JButton[,0,0,61x30,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.synth.SynthBorder@50f38cf0,flags=288,maximumSize=,minimumSize=,preferredSize=,defaultIcon=javax.swing.ImageIcon@6ae2d0b2,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=true,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=SVG,defaultCapable=false]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
按键输入事件始终生成“0”作为按键代码。改为查找方法 getKeyChar(),或者(如建议的那样)改为监听 keyReleased()。
getKeyChar(): http://goo.gl/ajH03
Key typed events ALWAYS generate '0' as the key code. Look up the method getKeyChar() instead, or (as has been suggested) listen for keyReleased() instead.
getKeyChar(): http://goo.gl/ajH03
更好的是实现KeyBindings
键盘的一部分是内置 JComponent 功能的保留键,更多信息来自@camickrs UIManager 默认值
取决于您需要实现KeyListener的原因,因为对于各种JComponent还有很多其他侦听器,应该在内部过滤或注册文本更改
一些 JComponent 模型从鼠标和键盘输入生成的事件
better would be implements KeyBindings
part of keyboard are reserved Keys for built-in JComponent funcionality, more informations from @camickrs UIManager Defaults
depends of reason(s) why you needed implents KeyListener, because for there are lots of another Listeners for various JComponent, that should be filtering or register text changes inside
some of JComponent Models generated Events from Mouse and Keyboard input
来自 JavaDoc
“按键输入”事件。输入字符时生成此事件。在最简单的情况下,它是由单个按键产生的。然而,字符通常是由一系列按键产生的,并且从按键事件到按键输入事件的映射可能是多对一或多对多。
您正在尝试获取 F5 键这可能没有注册为正在输入的字符。通过使用 KEY_RELEASED,您将始终获得您正在寻找的结果,并且 API 的行为符合预期。
From the JavaDoc
The "key typed" event. This event is generated when a character is entered. In the simplest case, it is produced by a single key press. Often, however, characters are produced by series of key presses, and the mapping from key pressed events to key typed events may be many-to-one or many-to-many.
You are trying to get the F5 key which is probably not registered as a character being entered. By using the KEY_RELEASED you will consistently get the result you are looking for and the API is behaving as expected.