JNA KeyboardUtils.isPressed 不能使用箭头键

JNA KeyboardUtils.isPressed not working with arrow keys

我正在尝试创建一个示例,调用 JNA 的 KeyboardUtils class 来检查 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。但是,从未检测到箭头键 Left/Right/Up/Down。

将代码转换为 C++ 并调用 Win32 GetAsyncKeyState() 确实可以使用箭头键。

根据网络,KeyEvent.VK_DOWN matches the Win32 definition的值(40)。

知道为什么 JNA 没有正确检测到箭头键吗?

根据 KeyboardUtils source codeKeyboardUtils 在任何平台上根本不支持箭头键。

KeyboardUtils 仅针对 3 个键盘平台实现 - Windows、Mac 和 Linux.

在 Mac 上,isPressed() 根本没有实现,所有键代码 returns 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(),正如您已经发现的那样。