Lui*_*iro 18 java swing keypress autorepeat keyrelease
(为清晰起见编辑)
我想检测用户何时按下并释放Java Swing中的键,忽略键盘自动重复功能.我还想在Linux,Mac OS和Windows上使用纯Java方法.
要求:
我在Java中面临的问题是,在Linux下,当用户持有一些密钥时,有许多keyPress和keyRelease事件被触发(因为键盘重复功能).
我尝试了一些没有成功的方法:
这是代码的基本(非工作)部分:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
当用户持有密钥(即"p")时,系统显示:
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
...
Run Code Online (Sandbox Code Playgroud)
至少在Linux下,JVM会在保持密钥时重新发送所有关键事件.为了使事情变得更加困难,在我的系统(Kubuntu 9.04 Core 2 Duo)上,时间戳不断变化.JVM使用相同的时间戳发送密钥新版本和新密钥.这使得很难知道密钥何时真正发布.
有任何想法吗?
谢谢
这可能有问题。我不记得了(已经很长时间了),但很可能重复键功能(由底层操作系统处理,而不是 Java)没有为 JVM 开发人员提供足够的信息来区分那些额外的来自“真实”事件的关键事件。(顺便说一下,我在 1.1.x 中的 OS/2 AWT 中处理过这个问题)。
来自 KeyEvent 的 javadoc:
“按键按下”和“按键释放”事件是较低级别的,取决于平台和键盘布局。每当按下或释放键时都会生成它们,并且是找出不生成字符输入的键(例如,操作键、修饰键等)的唯一方法。按下或释放的键由 getKeyCode 方法指示,该方法返回一个虚拟键代码。
我记得在 OS/2 中这样做(当时它仍然只有 2 事件向上/向下键盘处理的风格,就像旧版本的 Windows,而不是你在更多的 3 事件向上/向下/字符风格现代版本),如果只是按住键并且事件自动生成,我不会以任何不同的方式报告 KeyReleased 事件;但我怀疑 OS/2 甚至没有向我报告该信息(记不清了)。我们使用来自 Sun 的 Windows 参考 JVM 作为我们开发 AWT 的指南 - 所以我怀疑是否可以在那里报告这些信息,我至少会在他们的最后看到它。
好吧,你说在按键重复的情况下按键事件之间的时间可能是非负的。即便如此,它也可能很短。然后,您可以将此时间阈值设置为某个非常小的值,并且等于或低于该值的所有内容都被视为关键重复。