我正在尝试创建一个调用 JNA 的 KeyboardUtils
类来检查 Windows 上的按键状态的示例(类似于 Win32 的 GetAsyncKeyState()
)。
这是我的代码:
package com.foo;
import com.sun.jna.platform.KeyboardUtils;
import java.awt.event.KeyEvent;
public class Main {
public static void main(String[] args) {
new Thread() {
@Override
public void run() {
System.out.println("Watching for Left/Right/Up/Down or WASD. Press Shift+Q to quit");
while (true) {
try
{
Thread.sleep(10);
if (KeyboardUtils.isPressed(KeyEvent.VK_DOWN) || KeyboardUtils.isPressed(KeyEvent.VK_S) )
{
System.out.println("Down");
}
if (KeyboardUtils.isPressed(KeyEvent.VK_UP) || KeyboardUtils.isPressed(KeyEvent.VK_W) )
{
System.out.println("Up");
}
if (KeyboardUtils.isPressed(KeyEvent.VK_LEFT) || KeyboardUtils.isPressed(KeyEvent.VK_A) )
{
System.out.println("Left");
}
if (KeyboardUtils.isPressed(KeyEvent.VK_RIGHT) || KeyboardUtils.isPressed(KeyEvent.VK_D) )
{
System.out.println("Right");
}
if (KeyboardUtils.isPressed(KeyEvent.VK_Q) && KeyboardUtils.isPressed(KeyEvent.VK_SHIFT) )
{
break;
}
}
catch(Exception e)
{ }
}
System.exit(0);
}
}.start();
}
}
这工作正常,可以检测 WASD 键以及 Shift+Q。但是,永远不会检测到方向键左/右/上/下。
将代码转换为 C++ 并调用 Win32 GetAsyncKeyState()
可以使用箭头键。
根据网络,KeyEvent.VK_DOWN
的值匹配 Win32 definition (40)。
知道为什么 JNA 无法正确检测箭头键吗?
最佳答案
根据KeyboardUtils
source code ,KeyboardUtils
在任何平台上都不支持箭头键。
KeyboardUtils
仅针对 3 个键盘平台实现 - Windows、Mac 和 Linux。
在 Mac 上,isPressed()
根本没有实现,并且对所有按键代码都返回 false,并且当 KeyboardUtils
时会抛出 UnsupportedOperationException
。已初始化。
在 Windows 和 Linux 上,KeyboardUtils
支持以下键:
VK_A
-VK_Z
VK_0
-VK_9
VK_SHIFT
VK_CONTROL
VK_ALT
VK_META
(仅限 Linux)
在 Windows 上,KeyboardUtils.isPressed()
将 KeyEvent
键代码转换为 Win32 虚拟键代码(在 W32KeyboardUtils.toNative()
中),并且将它们传递给 GetAsyncKeyState()
(在 W32KeyboardUtils.isPressed()
中)。但箭头键未被处理并被转换为虚拟键代码 0,这不是有效的键代码。
与Linux关键代码类似。
因此,要检测 Windows 上的箭头键,您必须自己调用 GetAsyncKeyState()
,正如您已经发现的那样。
关于java - JNA KeyboardUtils.isPressed 无法使用箭头键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57546794/