这两天做一个IP地址的控件,在键盘监听遇到一点麻烦,症状就是无法截获键盘字符输入的事件,经过艰苦的调查,才知道原来是对swing的key event机制了解不深,将截获代码写在了keyPressed
处理方法中,而不是keyTyped。 而键盘输入一个字符时,key pressed, key typed 和 key released 事件都会产生(特定情况),所以在key pressed代码中event.consume()只是截获了key pressed事件,
但是key typed事件仍然会传递到控件。
附上详细的java doc描述,戒除浮躁,java doc还是要常看的,尤其是遇到问题的时候,盲目的试验,不如仔细地研究java doc或者源码
 
public class KeyEvent
extends InputEvent

An event which indicates that a keystroke occurred in a component.

This low-level event is generated by a component object (such as a text field) when a key is pressed, released, or typed. The event is passed to every KeyListener or KeyAdapter object which registered to receive such events using the component's addKeyListener method. (KeyAdapter objects implement the KeyListener interface.) Each such listener object gets this KeyEvent when the event occurs.

"Key typed" events are higher-level and generally do not depend on the platform or keyboard layout. They are generated when a Unicode character is entered, and are the preferred way to find out about character input. In the simplest case, a key typed event is produced by a single key press (e.g., 'a'). Often, however, characters are produced by series of key presses (e.g., 'shift' + 'a'), and the mapping from key pressed events to key typed events may be many-to-one or many-to-many. Key releases are not usually necessary to generate a key typed event, but there are some cases where the key typed event is not generated until a key is released (e.g., entering ASCII sequences via the Alt-Numpad method in Windows). No key typed events are generated for keys that don't generate Unicode characters (e.g., action keys, modifier keys, etc.).

The getKeyChar method always returns a valid Unicode character or CHAR_UNDEFINED. Character input is reported by KEY_TYPED events: KEY_PRESSED and KEY_RELEASED events are not necessarily associated with character input. Therefore, the result of the getKeyChar method is guaranteed to be meaningful only for KEY_TYPED events.

getKeyChar 方法的返回结果只有在KEY_TYPED事件处理代码可以保证,也即该方法应该在KEY_PRESSED 代码处理中调用

For key pressed and key released events, the getKeyCode method returns the event's keyCode. For key typed events, the getKeyCode method always returns VK_UNDEFINED.

"Key pressed" and "key released" events are lower-level and depend on the platform and keyboard layout. They are generated whenever a key is pressed or released, and are the only way to find out about keys that don't generate character input (e.g., action keys, modifier keys, etc.). The key being pressed or released is indicated by the getKeyCode method, which returns a virtual key code.

Virtual key codes are used to report which keyboard key has been pressed, rather than a character generated by the combination of one or more keystrokes (such as "A", which comes from shift and "a").

For example, pressing the Shift key will cause a KEY_PRESSED event with a VK_SHIFT keyCode, while pressing the 'a' key will result in a VK_A keyCode. After the 'a' key is released, a KEY_RELEASED event will be fired with VK_A. Separately, a KEY_TYPED event with a keyChar value of 'A' is generated.

Pressing and releasing a key on the keyboard results in the generating the following key events (in order):

    KEY_PRESSED
    KEY_TYPED (is only generated if a valid Unicode character could be generated.)
    KEY_RELEASED
 
But in some cases (e.g. auto-repeat or input method is activated) the order could be different (and platform dependent).

Notes:

  • Key combinations which do not result in Unicode characters, such as action keys like F1 and the HELP key, do not generate KEY_TYPED events.
  • Not all keyboards or systems are capable of generating all virtual key codes. No attempt is made in Java to generate these keys artificially.
  • Virtual key codes do not identify a physical key: they depend on the platform and keyboard layout. For example, the key that generates VK_Q when using a U.S. keyboard layout will generate VK_A when using a French keyboard layout.
  • Not all characters have a keycode associated with them. For example, there is no keycode for the question mark because there is no keyboard for which it appears on the primary layer.
  • In order to support the platform-independent handling of action keys, the Java platform uses a few additional virtual key constants for functions that would otherwise have to be recognized by interpreting virtual key codes and modifiers. For example, for Japanese Windows keyboards, VK_ALL_CANDIDATES is returned instead of VK_CONVERT with the ALT modifier.
  • As specified in Focus Specification key events are dispatched to the focus owner by default.

WARNING: Aside from those keys that are defined by the Java language (VK_ENTER, VK_BACK_SPACE, and VK_TAB), do not rely on the values of the VK_ constants. Sun reserves the right to change these values as needed to accomodate a wider range of keyboards in the future.