如何知道用户何时真正发布了Java中的密钥? [英] How to know when a user has really released a key in Java?

查看:148
本文介绍了如何知道用户何时真正发布了Java中的密钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(为清晰起见编辑)

我想检测用户何时在Java Swing中按下并释放键,忽略键盘自动重复功能。我也希望在Linux,Mac OS和Windows上使用纯Java方法。

I want to detect when a user presses and releases a key in Java Swing, ignoring the keyboard auto repeat feature. I also would like a pure Java approach the works on Linux, Mac OS and Windows.

要求:


  1. 当用户按下某个键时,我想知道它是什么键;

  2. 当用户释放某个键时,我想知道它是什么键;

  3. 我想忽略系统自动重复选项:我希望每次按键时只收到一个按键事件,每个按键释放只发一个按键释放事件;

  4. 如果可能的话,我会使用第1至第3项来确定用户是否一次持有多个键(即,她点击'a'并且没有释放它,她点击Enter)。

  1. When the user presses some key I want to know what key is that;
  2. When the user releases some key, I want to know what key is that;
  3. I want to ignore the system auto repeat options: I want to receive just one keypress event for each key press and just one key release event for each key release;
  4. If possible, I would use items 1 to 3 to know if the user is holding more than one key at a time (i.e, she hits 'a' and without releasing it, she hits "Enter").

我在Java中面临的问题是,在Linux下,当用户持有一些密钥时,有许多keyPress和keyRelease事件被触发(因为键盘重复功能)。

The problem I'm facing in Java is that under Linux, when the user holds some key, there are many keyPress and keyRelease events being fired (because of the keyboard repeat feature).

我尝试了一些没有成功的方法


  1. 获取上次关键事件发生的时间ed - 在Linux中,它们似乎为零重复,但是,在Mac OS中它们不是;

  2. 仅当当前keyCode与最后一个不同时才考虑事件 - 这用户无法连续两次敲击同一个键的方式;

以下是代码的基本(非工作)部分:

Here is the basic (non working) part of code:

import java.awt.event.KeyListener;

public class Example implements KeyListener {

public void keyTyped(KeyEvent e) {
}

public void keyPressed(KeyEvent e) {
    System.out.println("KeyPressed: "+e.getKeyCode()+", ts="+e.getWhen());
}

public void keyReleased(KeyEvent e) {
    System.out.println("KeyReleased: "+e.getKeyCode()+", ts="+e.getWhen());
}

}

当用户持有钥匙时(即'p')系统显示:

When a user holds a key (i.e, 'p') the system shows:

KeyPressed:  80, ts=1253637271673
KeyReleased: 80, ts=1253637271923
KeyPressed:  80, ts=1253637271923
KeyReleased: 80, ts=1253637271956
KeyPressed:  80, ts=1253637271956
KeyReleased: 80, ts=1253637271990
KeyPressed:  80, ts=1253637271990
KeyReleased: 80, ts=1253637272023
KeyPressed:  80, ts=1253637272023
...

至少在Linux下,JVM会在保持密钥时重新发送所有关键事件。为了使事情变得更加困难,在我的系统(Kubuntu 9.04 Core 2 Duo)上,时间戳不断变化。 JVM使用相同的时间戳发送密钥新版本和新密钥。这使得很难知道密钥何时真正发布。

At least under Linux, the JVM keeps resending all the key events when a key is being hold. To make things more difficult, on my system (Kubuntu 9.04 Core 2 Duo) the timestamps keep changing. The JVM sends a key new release and new key press with the same timestamp. This makes it hard to know when a key is really released.

任何想法?

谢谢

推荐答案

此问题重复此处

在该问题中,链接指向提供了Sun bug游行,建议采用一些解决方法。

In that question, a link to the Sun bug parade is given, where some workaround is suggested.

我已经黑客攻击实现为AWTEventListener,可以在应用程序的开头安装。

I've made a hack implemented as an AWTEventListener that can be installed at the start of the application.

基本上,请注意RELEASED和后续PRESSED之间的时间很短 - 实际上,它是0毫升。因此,您可以使用它作为度量:保持RELEASED一段时间,如果新的PRESSED紧随其后,则吞下RELEASED并处理PRESSED(因此您将获得与Windows相同的逻辑,这显然是正确的方法)。但是,请注意从一毫秒到下一秒的换行(我已经看到过这种情况) - 因此请至少使用1 ms进行检查。为了解释滞后和诸如此类的事情,大约20-30毫秒可能不会受到伤害。

Basically, observe that the time between the RELEASED and the subsequent PRESSED is small - actually, it is 0 millis. Thus, you can use that as a measure: Hold the RELEASED for some time, and if a new PRESSED comes right after, then swallow the RELEASED and just handle the PRESSED (And thus you will get the same logic as on Windows, which obviously is the correct way). However, watch for the wrap-over from one millisecond to the next (I've seen this happen) - so use at least 1 ms to check. To account for lags and whatnots, some 20-30 milliseconds probably won't hurt.

这篇关于如何知道用户何时真正发布了Java中的密钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆