使用JNativeHook注册多键按压

时间:2014-10-06 13:05:17

标签: java

我查看了一些示例,并尝试在Google上搜索了几个小时,但似乎我找不到涵盖我要问的问题。

如果我想做某事

同时使用W + A,并将其作为单独的键事件注册,而不是单独注册为W和A,我将如何使用JNativeHook进行此操作?是因为我在某个地方错过了一个涵盖这个问题的课程,还是只有一种解决方法才能读取一个关键字?

我正在尝试在控制台中执行此操作(因此我使用此库而不是Swing)。

我举了他们的例子,想尝试修改它:

import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;

public class GlobalKeyListener implements NativeKeyListener {

    @Override
    public void nativeKeyPressed(NativeKeyEvent e) {
        System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));

        if (e.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
            GlobalScreen.unregisterNativeHook();
        }
    }

    @Override
    public void nativeKeyReleased(NativeKeyEvent e) {
        System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
    }

    @Override
    public void nativeKeyTyped(NativeKeyEvent e) {
        System.out.println("Key Typed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
    }

    public static void main(String[] args) {
        try {
            GlobalScreen.registerNativeHook();
        } catch (NativeHookException ex) {
            System.err.println("There was a problem registering the native hook.");
            System.err.println(ex.getMessage());

            System.exit(1);
        }

        //Construct the example object and initialze native hook.
        GlobalScreen.getInstance().addNativeKeyListener(new GlobalKeyListener());
    }
}

2 个答案:

答案 0 :(得分:5)

您需要监听所需组合的每个单独的按键和释放事件,并在按下每个按键时设置某种标记。如果按下其中一个所需的键,并且满足标志条件,则可以执行将这些键按在一起时需要执行的操作。如果不创建自定义键盘驱动程序,则无法为两个键获取单个事件。如果您的目标是在按下W和A键事件之前按下它们,请查看Wiki的unsupported consuming events部分。请注意,事件抑制仅适用于Windows和OS X目标,并且抑制的事件不会传递给其他应用程序。

它不是最漂亮的例子,但它应该做你想要的。

private short hotKeyFlag = 0x00;
private static final short MASK_A = 1 << 0;
private static final short MASK_W = 1 << 1;

...
@Override
public void nativeKeyPressed(NativeKeyEvent e) {
    if (e.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
        GlobalScreen.unregisterNativeHook();
    }
    else if (e.getKeyCode() == NativeKeyEvent.VK_A) {
        hotKeyFlag &= MASK_A;

        // Check the mask and do work.
        if (hotKeyFlag == MASK_A & MASK_W) {
            // Fire Shortcut.
        }
    }
    else if (e.getKeyCode() == NativeKeyEvent.VK_W) {
        hotKeyFlag &= MASK_W;

        // Check the mask and do work.
        if (hotKeyFlag == MASK_A & MASK_W) {
            // Fire Shortcut.
        }
    }
}

@Override
public void nativeKeyReleased(NativeKeyEvent e) {
    if (e.getKeyCode() == NativeKeyEvent.VK_A) {
        hotKeyFlag ^= MASK_A;
    }
    else if (e.getKeyCode() == NativeKeyEvent.VK_W) {
        hotKeyFlag ^= MASK_W;
    }
}

答案 1 :(得分:4)

这是我的答案: -

private boolean a = false, w = false;

@Override
public void nativeKeyPressed(NativeKeyEvent e) {
    if (e.getKeyCode() == NativeKeyEvent.VC_A) {
        a = true;
        if (w) {
            System.out.println("W+A");
        } else {//remove this else only for testing
            System.out.println("Only A");
        }
    } else if (e.getKeyCode() == NativeKeyEvent.VC_W) {
        w = true;
        if (a) {
            System.out.println("A+W");
        } else {//remove this else only for testing
            System.out.println("Only W");
        }
    }
}

@Override
public void nativeKeyReleased(NativeKeyEvent e) {
    if (e.getKeyCode() == NativeKeyEvent.VC_A) {
        a = false;
    } else if (e.getKeyCode() == NativeKeyEvent.VC_W) {
        w = false;
    }
}

@Override
public void nativeKeyTyped(NativeKeyEvent e) {
    //System.out.println("Key Typed: " + e.getKeyText(e.getKeyCode()));
}