java和VB中按键事件处理:解析 KeyCode、KeyAscii; KeyDown/KeyUp/KeyPress 的关系区别及应用

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: java和VB中按键事件处理:解析 KeyCode、KeyAscii; KeyDown/KeyUp/KeyPress 的关系区别及应用

一、 背景

    一个小需求:在下拉组合框中输入数字。

    写代码的时候考虑了一下是使用keydown还是keypress,也就是此时想深入写一篇文章,关于keydown和keypress的区别,还有代码中涉及的两个函数:KeyCode和KeyAscii,另外和Java中的相关内容做一个对比学习。

    先看这个小例子的实现:

  • 使用keydown
Private Sub Combo1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    If KeyCode = 13 Then  ' 判断是否按下回车键
        Combo1.AddItem Combo1.Text  ' 将文本框内容添加到组合框中
        Combo1.Text = ""  ' 清空文本框内容
    End If
End Sub

*使用keyPress

Private Sub Combo1_KeyPress(KeyAscii As Integer)
If KeyAscii = 13 Then
    Combo1.AddItem Combo1.Text
    Combo1.SelStart = 0
    Combo1.SelLength = Len(Combo1.Text)
    Text1.Text = Combo1.ListCount
End If

二、KeyCode和KeyAscii

    在编程中,我们常常需要获取按键的值来进行相应的处理。在 Visual Basic中,有两个与按键相关的函数:KeyCode 和 KeyAscii。

  • KeyCode 是一个整型值,表示按键的键码值。对于可打印字符(如字母、数字、标点符号等),其值与 ASCII 码相同。
  • KeyAscii 是一个整型值,表示按键的 ASCII 码值。只对可打印字符有效,对于不可打印字符(如方向键、F1~F12 等),其值为零。

    这里要注意非字符键是没有ASCII 值的。

    因为 ASCII是一种将字符与其对应的数字编码相互映射的标准。它只定义了 0 到 127 之间的字符编码,用于表示英文字符、数字和一些基本的符号。然而,功能键、控制键等非字符键并不属于这个字符集范围内,因此它们没有相应的 ASCII 值。

    相反,非字符键通常被映射为一个数值键码,也就是KeyCode,在 KeyDown 或 KeyUp 事件中可以使用这个键码来识别非字符键。不同的编程语言和操作系统可能会有自己的键码映射表,可以参考相应的文档或运行时库来获取特定按键的键码值。

    所以,在处理非字符键时,应使用 KeyDown 或 KeyUp 事件配合 KeyCode 值进行判断,而不是使用 KeyPress 事件和 ASCII 值

2.1 VB中的KeyCode和KeyAscii

    在VB中,可以使用 KeyCode 来获取按键的键码值,使用 KeyAscii 来获取按键的 ASCII 码值。以下是一个简单的示例代码:

Private Sub TextBox1_KeyDown(KeyCode As Integer, Shift As Integer)
    Dim asciiValue As Integer
    asciiValue = KeyAscii
    ' 判断按下的键是否是可打印字符
    If asciiValue > 0 And asciiValue < 127 Then
        ' 处理可打印字符
        ' ...
    Else
        ' 处理不可打印字符
        ' ...
    End If
End Sub

2.2 java中的KeyEvent.getKeyCode()

  • 在 Java 中,与 KeyCode 对应的是 KeyEvent.getKeyCode() 方法,用于获取按键的整数键码值。
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class MyKeyListener implements KeyListener {
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        // 打印按键的键码值
        System.out.println("键码值:" + keyCode);
        // 处理特定的键码值
        if (keyCode == KeyEvent.VK_ENTER) {
            // 处理回车键的操作
            System.out.println("按下了回车键");
        } else if (keyCode == KeyEvent.VK_ESCAPE) {
            // 处理ESC键的操作
            System.out.println("按下了ESC键");
        } else {
            // 处理其他键码值
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // 处理释放按键的事件
    }
    @Override
    public void keyTyped(KeyEvent e) {
        // 处理按键字符输入的事件
    }
}

    在上面的代码中,实现了 KeyListener 接口,并重写了它的方法。在 keyPressed() 方法中,使用 e.getKeyCode() 来获取按键的键码值。然后,打印出键码值,并根据定义在 KeyEvent 类中的常量(如 KeyEvent.VK_ENTER 或 KeyEvent.VK_ESCAPE)与特定的键码值进行比较来处理相应的操作。

    要使用这个按键监听器,可以将它添加到接收键盘输入的组件上,例如文本框或面板。以下是一个将按键监听器添加到文本框的示例:

import javax.swing.JFrame;
import javax.swing.JTextField;
public class Main {
    public static void main(String[] args) {
        JFrame frame = new JFrame("按键监听器示例");
        JTextField textField = new JTextField();
        // 将按键监听器添加到文本框上
        textField.addKeyListener(new MyKeyListener());
        frame.add(textField);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

    当运行这段代码时,只要文本框具有焦点,按下任意键时 keyPressed() 方法就会被触发。可以根据需要自定义 keyPressed() 方法中的代码来处理不同的键码值。

    在图形用户界面(GUI)应用程序中,最好使用Swing或JavaFX等框架提供的更高级的事件处理机制,而不是直接实现 KeyListener 接口。但是为了说明问题,这个示例演示了在简单情境下使用 KeyEvent.getKeyCode() 的用法。

  • KeyAscii 的概念在 Java 中并不存在。也没有直接对应于 KeyAscii 的内置函数或类。
    在 Java 中,可以使用 KeyEvent 类的 getKeyCode() 方法来获取按键的整数键码值。如果需要获取按键的字符(Unicode 码),可以使用 KeyEvent 类的 getKeyChar() 方法。

示例代码:

import java.awt.event.KeyEvent;
public class MyKeyListener implements KeyEvent {
    @Override
    public void keyTyped(KeyEvent e) {
        // 获取按键的字符(Unicode 码)
        char keyChar = e.getKeyChar();
        System.out.println("按下的字符:" + keyChar);
    }
    @Override
    public void keyPressed(KeyEvent e) {
        // 获取按键的整数键码值
        int keyCode = e.getKeyCode();
        System.out.println("按下的键码值:" + keyCode);
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // 按键释放事件
    }
}

需要注意的是,在 Java 中,字符的表示方式使用 Unicode 码(UTF-16 编码),与 ASCII 码并不完全一致。因此,如果你需要判断按键的字符是否是某个特定的 ASCII 字符,可以通过比较其对应的 Unicode 码值。

三、KeyDown、KeyUp和KeyPress

3.1 VB中的KeyDown、KeyUp和KeyPress

在 VB中,还有三个与按键事件相关的事件:KeyDown、KeyUp 和 KeyPress。

  • KeyDown 事件在按键被按下后立即发生。
  • KeyUp 事件在按键被释放后立即发生。
  • KeyPress 事件在按键被按下后,在其对应的字符被插入到文本框或标签等控件中时发生。

    在 Visual Basic中,可以使用这三个事件来处理按键事件。以下是一个示例代码:

Private Sub TextBox1_KeyDown(KeyCode As Integer, Shift As Integer)
    ' 处理键盘按下事件
    ' ...
End Sub
Private Sub TextBox1_KeyUp(KeyCode As Integer, Shift As Integer)
    ' 处理键盘释放事件
    ' ...
End Sub
Private Sub TextBox1_KeyPress(KeyAscii As Integer)
    ' 处理键盘按下并字符插入事件
    ' ...
End Sub

3.2 Java中的按键事件处理

    在 Java 中,需要实现 KeyListener 接口,并重写相应的方法来监听和处理按键事件。

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class MyKeyListener implements KeyListener {
    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        // 判断按下的键是否是功能键
        if (e.isActionKey()) {
            // 处理功能键
            // ...
        } else {
            // 处理可打印字符
            char keyChar = e.getKeyChar();
            // ...
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // 处理键盘释放事件
        // ...
    }
    @Override
    public void keyTyped(KeyEvent e) {
        // 处理键盘按下并字符插入事件
        // ...
    }
}

    以上是一个实现了 KeyListener 接口的示例代码。在需要监听按键事件的地方,可以将该监听器注册到对应的组件上,如文本框:

JTextField textField = new JTextField();
textField.addKeyListener(new MyKeyListener());

需要注意的是,在容器类组件(如面板和窗口)默认情况下不支持键盘事件监听,需要手动将焦点设置到该组件上,并添加键盘事件监听器才能生效。

四、在VB和java中的区别

    在 VB和 Java 中,都有处理按键事件的 API,但二者之间还是存在一些差别。

    在 Java 中,需要通过实现 KeyListener 接口来监听和处理按键事件。该接口定义了三个方法:keyPressed、keyReleased 和 keyTyped。

    keyPressed(KeyEvent e) 方法在按键被按下后立即触发。它接收一个 KeyEvent 参数 e,该参数包含有关按键事件的信息。在该方法中,可以通过 e.getKeyCode() 获取按键的整数键码值,通过 e.isActionKey() 判断按键是否是功能键(如方向键、F1~F12 等),通过 e.getKeyChar() 获取按键对应的字符的 Unicode 码,通过 e.getKeyLocation() 获取按键在键盘上的位置等。根据具体需求,可以在该方法中编写相应的逻辑来处理按键事件。

    keyReleased(KeyEvent e) 方法在按键被释放后立即触发。同样,它也接收一个 KeyEvent 参数 e,可以使用其中的方法获取按键相关信息。在该方法中,可以处理按键释放后的逻辑,比如重置某些状态或执行其他操作。

    keyTyped(KeyEvent e) 方法在按键被按下后,在其对应的字符被插入到文本框或标签等控件中时触发。同样地,它也接收一个 KeyEvent 参数 e,可以使用其中的方法获取按键相关信息。在该方法中,可以处理插入字符后的逻辑,例如限制输入的字符类型、实时显示输入内容等。

    在使用 KeyListener 接口时,需要将其注册到相应的组件上,以便监听该组件的按键事件。例如,可以使用 addKeyListener() 方法将 KeyListener 对象添加到文本框控件上,从而监听该文本框的按键事件。

    需要注意的是,不是所有的组件都支持键盘事件监听。例如,容器类组件(如面板和窗口)默认情况下不支持键盘事件监听,需要手动将焦点设置到该组件上,并添加键盘事件监听器才能生效。

    综上所述,通过实现 KeyListener 接口并重写相应的方法,可以实现在 Java 中监听和处理按键事件的功能。根据具体需求,可以在相应的方法中编写逻辑来响应按键事件,以实现特定的功能。

4.1 在VB中的特点:

1、可以使用 KeyAscii 来获取按键的 ASCII 码值。这个概念在 Java 中并不存在,因为 Java 中的字符表示方式使用 Unicode 码。

2、按键事件中常常用到的是 KeyCode 属性。而在 Java 中,则是使用 KeyEvent 类和 getKeyCode() 方法来获取按键的整数键码值。

3、KeyDown、KeyUp 和 KeyPress 事件都是内置的事件,可以直接使用。而在 Java 中,需要实现 KeyListener 接口,并重写相应的方法来监听和处理按键事件。

4.2 在Java中的特点:

1、字符的表示方式使用 Unicode 码(UTF-16 编码),与 ASCII 码并不完全一致。因此,如果需要判断按键的字符是否是某个特定的 ASCII 字符,可以通过比较其对应的 Unicode 码值。

2、KeyEvent 类提供了丰富的方式来获取和操作按键事件。例如,isActionKey() 方法可以用来判断一个按键是否是功能键(如方向键、F1~F12 等);getKeyChar() 方法可以获取对应字符的 Unicode 值;getKeyLocation() 方法可以获取按键在键盘上的位置等等。

3、除了 KeyListener 接口外,还提供了一系列专门用于处理特定控件类型的监听器接口,如 MouseListener、WindowListener、ActionListener 等。

综上所述,虽然 VB 和 Java 中都有处理按键事件的 API,但二者之间还是存在一些差别,需要根据具体情况进行选择和使用。

4.3 表格对比

特点 Visual Basic Java
获取按键的 ASCII 码值 使用 KeyAscii 通过 Unicode 码表示字符
获取按键的整数键码值 使用 KeyCode 属性 使用 KeyEvent 类和 getKeyCode() 方法
内置的按键事件 KeyDown、KeyUp 和 KeyPress 事件 需要实现 KeyListener 接口并重写方法
字符表示方式 ASCII 码 Unicode 码(UTF-16 编码)
判断功能键 使用 isActionKey() 方法
获取按键对应字符的 Unicode 码 使用 getKeyChar() 方法
获取按键在键盘上的位置 使用 getKeyLocation() 方法
其他监听器接口 提供了一系列专门用于处理特定控件类型的监听器接口
容器类组件的键盘事件监听 默认不支持 需要手动设置焦点并添加键盘事件监听器

五、总结:

    本文主要讲解了如何通过使用 KeyCode 和 KeyAscii 在 VB中获取按键的键码值和 ASCII 码值,并使用 KeyDown、KeyUp 和 KeyPress 事件来处理按键事件,同时还介绍了在 Java 中,需要实现 KeyListener 接口,并重写相应的方法来监听和处理按键事件。在开发过程中,根据具体需求,可以编写逻辑来响应按键事件,以实现特定的功能。

相关文章
|
18天前
|
机器学习/深度学习 人工智能 自然语言处理
AI技术深度解析:从基础到应用的全面介绍
人工智能(AI)技术的迅猛发展,正在深刻改变着我们的生活和工作方式。从自然语言处理(NLP)到机器学习,从神经网络到大型语言模型(LLM),AI技术的每一次进步都带来了前所未有的机遇和挑战。本文将从背景、历史、业务场景、Python代码示例、流程图以及如何上手等多个方面,对AI技术中的关键组件进行深度解析,为读者呈现一个全面而深入的AI技术世界。
90 10
|
4天前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
48 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
11天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
8天前
|
安全 API 数据安全/隐私保护
速卖通AliExpress商品详情API接口深度解析与实战应用
速卖通(AliExpress)作为全球化电商的重要平台,提供了丰富的商品资源和便捷的购物体验。为了提升用户体验和优化商品管理,速卖通开放了API接口,其中商品详情API尤为关键。本文介绍如何获取API密钥、调用商品详情API接口,并处理API响应数据,帮助开发者和商家高效利用这些工具。通过合理规划API调用策略和确保合法合规使用,开发者可以更好地获取商品信息,优化管理和营销策略。
|
9天前
|
Java 数据库连接 Spring
反射-----浅解析(Java)
在java中,我们可以通过反射机制,知道任何一个类的成员变量(成员属性)和成员方法,也可以堆任何一个对象,调用这个对象的任何属性和方法,更进一步我们还可以修改部分信息和。
|
29天前
|
机器学习/深度学习 搜索推荐 API
淘宝/天猫按图搜索(拍立淘)API的深度解析与应用实践
在数字化时代,电商行业迅速发展,个性化、便捷性和高效性成为消费者新需求。淘宝/天猫推出的拍立淘API,利用图像识别技术,提供精准的购物搜索体验。本文深入探讨其原理、优势、应用场景及实现方法,助力电商技术和用户体验提升。
|
9天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
11天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
11天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
11天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
35 3

热门文章

最新文章

推荐镜像

更多