JNA KeyboardUtils.isPressed无法使用箭头键

时间:2019-08-18 17:20:39

标签: java winapi jna

我正在尝试创建一个示例,该示例调用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无法正确检测箭头键吗?

1 个答案:

答案 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(),就像您已经发现的那样。