如何编写密钥侦听器
按键事件指示用户何时在键盘上键入。具体来说,当用户按下或释放键盘按键时,按键事件由具有键盘焦点的组件触发。有关焦点的详细信息,请参见如何使用 Focus 子系统。
Note:
要定义对特定键的特殊反应,请使用键绑定而不是键侦听器。有关更多信息,请参见如何使用键绑定。
发送有关两种基本键事件的通知:
-
键入 Unicode 字符
-
按下或释放键盘上的键
第一种事件称为“键类型”事件。第二种是按键或按键释放事件。
通常,除非您需要知道用户何时按下与字符不对应的键,否则您仅对键键入的事件做出反应。例如,要知道用户何时键入 Unicode 字符(无论是通过按“ a”之类的一个键还是依次按几个键),就可以处理键类型的事件。另一方面,要知道用户何时按下 F1 键,或者用户是否按下数字键盘上的“ 3”键,则可以处理按键事件。
Note:
要触发键盘事件,组件必须具有键盘焦点。
要使组件获得键盘焦点,请按照下列步骤操作:
-
确保组件的
isFocusable
方法返回true
。此状态允许组件接收焦点。例如,可以通过调用标签上的setFocusable(true)
方法为JLabel
组件启用键盘焦点。 -
确保适当时组件请求焦点。对于自定义组件,请实现一个鼠标侦听器,该鼠标侦听器在单击该组件时会调用
requestFocusInWindow
方法。
Version note:
焦点子系统使用焦点遍历键,例如 Tab 和 Shift Tab。如果需要防止消耗焦点遍历键,可以致电
component.setFocusTraversalKeysEnabled(false)
在触发关键事件的组件上。然后,您的程序必须自行处理焦点遍历。或者,您可以使用KeyEventDispatcher类来预听所有关键事件。 focus page包含有关焦点子系统的详细信息。
您可以获取有关特定按键事件的详细信息。例如,您可以查询按键事件,以确定是否从操作键中触发了该事件。操作键的示例包括复制,粘贴,向上翻页,撤消以及箭头键和功能键。您还可以查询按键或释放键的事件,以确定触发该事件的键的位置。大多数按键事件是从标准键盘触发的,但是某些按键的事件(例如 Shift)具有有关用户是否按下键盘左侧或右侧的 Shift 键的信息。同样,可以从标准键盘或数字键盘 Importing 数字“ 2”。
对于键类型的事件,您可以获得键字符值以及使用的所有修饰符。
Note:
除非它涉及键类型的事件,否则您不应依赖从getKeyChar
返回的键字符值。
下面的示例演示关键事件。它由一个您可以键入的文本字段组成,其后是一个文本区域,该文本区域在每次触发键事件时都会显示一条消息。窗口底部的按钮可让您同时清除文本字段和文本区域。
Try this:
-
单击启动按钮以使用Java™Web 开始(下载 JDK 7 或更高版本)运行 KeyEventDemo。另外,要自己编译和运行示例,请查阅example index。
-
按下并释放键盘上的 A 键,Importing 小写字母“ a”。
文本字段会触发三个事件:按键事件,按键类型事件和按键释放事件。请注意,键类型事件没有键代码信息,键按下事件和键释放事件没有键字符信息。到目前为止,没有一个事件来自修饰键或动作键,并且在按键和释放键的事件上报告的键位置很可能是标准的。 -
按清除按钮。
在执行以下每个步骤之后,您可能想要执行此操作。 -
按下并释放 Shift 键。
文本字段会触发两个事件:按下一个键和释放一个键。文本字段不会触发键类型的事件,因为 Shift 本身不对应任何字符。 -
通过按 Shift 和 A 键 Importing 大写的“ A”。
您将看到以下事件,尽管可能不是按此 Sequences 进行:键按下(Shift),键按下(A),键键入('A'),键释放(A),键释放(Shift) 。请注意,Shift 键被列为按键类型和按键事件的修改键。 -
按下并释放 Caps Lock 键,然后按 A 键,Importing 一个大写字母“ A”。
您应该看到以下事件:按下(Caps Lock),按下(A),键入('A'),释放(A)。请注意,大写锁定未*列为修饰键。 -
按 Tab 键。按键事件侦听器未接收到 Tab 键的按键事件或按键释放事件。这是因为焦点子系统使用焦点遍历键,例如 Tab 和 Shift Tab。再按两次 Tab 键可将焦点返回到文本区域。
-
按功能键,例如 F3.您会看到功能键是一个动作键。
-
按左 Shift 键,然后按右 Shift 键。键按下和键释放的事件指示键入了哪个 Shift 键。
-
如果键盘上有数字键盘,请按 Num Lock 键。
对于 Caps Lock,有一个按键事件,但没有按键释放事件。 -
按数字键盘上的“ 2”键。您会看到数字“ 2”的键按下,键键入和键释放事件。
-
按标准键盘上的“ 2”键。同样,您会看到三个事件消息。两个 2 号键的键类型事件是相同的。但是按键和按键释放事件指示不同的按键代码和不同的按键位置。
-
再按一次 Num Lock 键。触发键释放事件。
您可以在KeyEventDemo.java中找到示例的代码。这是演示的关键事件处理代码:
public class KeyEventDemo ... implements KeyListener ... {
...//where initialization occurs:
typingArea = new JTextField(20);
typingArea.addKeyListener(this);
//Uncomment this if you wish to turn off focus
//traversal. The focus subsystem consumes
//focus traversal keys, such as Tab and Shift Tab.
//If you uncomment the following line of code, this
//disables focus traversal and the Tab events
//become available to the key event listener.
//typingArea.setFocusTraversalKeysEnabled(false);
...
/** Handle the key typed event from the text field. */
public void keyTyped(KeyEvent e) {
displayInfo(e, "KEY TYPED: ");
}
/** Handle the key-pressed event from the text field. */
public void keyPressed(KeyEvent e) {
displayInfo(e, "KEY PRESSED: ");
}
/** Handle the key-released event from the text field. */
public void keyReleased(KeyEvent e) {
displayInfo(e, "KEY RELEASED: ");
}
...
private void displayInfo(KeyEvent e, String keyStatus){
//You should only rely on the key char if the event
//is a key typed event.
int id = e.getID();
String keyString;
if (id == KeyEvent.KEY_TYPED) {
char c = e.getKeyChar();
keyString = "key character = '" + c + "'";
} else {
int keyCode = e.getKeyCode();
keyString = "key code = " + keyCode
+ " ("
+ KeyEvent.getKeyText(keyCode)
+ ")";
}
int modifiersEx = e.getModifiersEx();
String modString = "extended modifiers = " + modifiersEx;
String tmpString = KeyEvent.getModifiersExText(modifiersEx);
if (tmpString.length() > 0) {
modString += " (" + tmpString + ")";
} else {
modString += " (no extended modifiers)";
}
String actionString = "action key? ";
if (e.isActionKey()) {
actionString += "YES";
} else {
actionString += "NO";
}
String locationString = "key location: ";
int location = e.getKeyLocation();
if (location == KeyEvent.KEY_LOCATION_STANDARD) {
locationString += "standard";
} else if (location == KeyEvent.KEY_LOCATION_LEFT) {
locationString += "left";
} else if (location == KeyEvent.KEY_LOCATION_RIGHT) {
locationString += "right";
} else if (location == KeyEvent.KEY_LOCATION_NUMPAD) {
locationString += "numpad";
} else { // (location == KeyEvent.KEY_LOCATION_UNKNOWN)
locationString += "unknown";
}
...//Display information about the KeyEvent...
}
}
密钥侦听器 API
对应的适配器类为KeyAdapter.
Method | Purpose |
---|---|
keyTyped(KeyEvent) | 在用户将 Unicode 字符 Importing 到侦听的组件中之后立即调用。 |
keyPressed(KeyEvent) | 在被监听的组件具有焦点时,用户按下按键后立即调用。 |
keyReleased(KeyEvent) | 在用户释放键并且焦点位于监听组件之后立即调用。 |
KeyEvent
类继承了InputEvent类的许多有用方法,例如getModifiersEx
,还继承了ComponentEvent和AWTEvent类的一些有用方法。有关完整列表,请参见mouse listener页中的InputEvent Class表。
Method | Purpose |
---|---|
int getKeyChar() | 获取与此事件关联的 Unicode 字符。对于键类型事件,仅依赖此值。 |
int getKeyCode() | 获取与此事件关联的键控代码。键码标识用户按下或释放的键盘上的特定键。 KeyEvent 类为常见的按键定义了许多按键代码常量。例如,VK_A 指定标记为 A 的键,而VK_ESCAPE 指定退出键。 |
String getKeyText(int) | |
String getKeyModifiersText(int) | 分别返回事件的键代码和修饰键的文本描述。 |
int getModifiersEx() 字符串getModifiersExText(int 修饰符) | 返回此事件的扩展修饰符掩码。有些方法是从InputEvent 类继承的。扩展修饰符表示所有 Pattern 键的状态。 getModifiersExText 方法返回一个字符串,描述扩展的修饰键和鼠标按钮。由于getModifiersEx 和getModifiersExText 方法提供了有关键事件的更多信息,因此它们比getKeyText 或getKeyModifiersText 方法更可取。 |
boolean isActionKey() | 如果引发事件的键是操作键,则返回 true。操作键的示例包括剪切,复制,粘贴,向上翻页,大写锁定,箭头和功能键。此信息仅对按键和按键释放事件有效。 |
int getKeyLocation() | 返回触发此事件的键的位置。这提供了一种方法来区分在键盘上多次出现的键,例如两个 Shift 键。可能的值为KEY_LOCATION_STANDARD ,KEY_LOCATION_LEFT ,KEY_LOCATION_RIGHT ,KEY_LOCATION_NUMPAD 或KEY_LOCATION_UNKNOWN 。对于键类型的事件,此方法始终返回KEY_LOCATION_UNKNOWN 。 |
使用键侦听器的示例
下表列出了使用键侦听器的示例。
Example | Where Described | Notes |
---|---|---|
KeyEventDemo | This section | 报告在文本字段上发生的所有关键事件,以演示触发关键事件的情况。 |