如何编写密钥侦听器

按键事件指示用户何时在键盘上键入。具体来说,当用户按下或释放键盘按键时,按键事件由具有键盘焦点的组件触发。有关焦点的详细信息,请参见如何使用 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返回的键字符值。

下面的示例演示关键事件。它由一个您可以键入的文本字段组成,其后是一个文本区域,该文本区域在每次触发键事件时都会显示一条消息。窗口底部的按钮可让您同时清除文本字段和文本区域。

KeyEventDemo.html

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

KeyListener interface

对应的适配器类为KeyAdapter.

MethodPurpose
keyTyped(KeyEvent)在用户将 Unicode 字符 Importing 到侦听的组件中之后立即调用。
keyPressed(KeyEvent)在被监听的组件具有焦点时,用户按下按键后立即调用。
keyReleased(KeyEvent)在用户释放键并且焦点位于监听组件之后立即调用。

KeyEvent 类

KeyEvent类继承了InputEvent类的许多有用方法,例如getModifiersEx,还继承了ComponentEventAWTEvent类的一些有用方法。有关完整列表,请参见mouse listener页中的InputEvent Class表。

MethodPurpose
int getKeyChar()获取与此事件关联的 Unicode 字符。对于键类型事件,仅依赖此值。
int getKeyCode()获取与此事件关联的键控代码。键码标识用户按下或释放的键盘上的特定键。 KeyEvent类为常见的按键定义了许多按键代码常量。例如,VK_A指定标记为 A 的键,而VK_ESCAPE指定退出键。
String getKeyText(int)

String getKeyModifiersText(int)
分别返回事件的键代码和修饰键的文本描述。
int getModifiersEx()
字符串getModifiersExText(int 修饰符)
返回此事件的扩展修饰符掩码。有些方法是从InputEvent类继承的。扩展修饰符表示所有 Pattern 键的状态。 getModifiersExText方法返回一个字符串,描述扩展的修饰键和鼠标按钮。由于getModifiersExgetModifiersExText方法提供了有关键事件的更多信息,因此它们比getKeyTextgetKeyModifiersText方法更可取。
boolean isActionKey()如果引发事件的键是操作键,则返回 true。操作键的示例包括剪切,复制,粘贴,向上翻页,大写锁定,箭头和功能键。此信息仅对按键和按键释放事件有效。
int getKeyLocation()返回触发此事件的键的位置。这提供了一种方法来区分在键盘上多次出现的键,例如两个 Shift 键。可能的值为KEY_LOCATION_STANDARDKEY_LOCATION_LEFTKEY_LOCATION_RIGHTKEY_LOCATION_NUMPADKEY_LOCATION_UNKNOWN。对于键类型的事件,此方法始终返回KEY_LOCATION_UNKNOWN

使用键侦听器的示例

下表列出了使用键侦听器的示例。

ExampleWhere DescribedNotes
KeyEventDemoThis section报告在文本字段上发生的所有关键事件,以演示触发关键事件的情况。