我正在尝试创建一个示例,该示例调用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无法正确检测箭头键吗?
答案 0 :(得分:1)
根据KeyboardUtils
source code, KeyboardUtils
在任何平台上根本不支持箭头键。
KeyboardUtils
仅针对3个键盘平台(Windows,Mac和Linux)实现。
在Mac上,isPressed()
完全没有实现,并且对于所有键代码都返回false,并且在初始化UnsupportedOperationException
时抛出KeyboardUtils
。
在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()
,就像您已经发现的那样。