如何按需停用 jnativehook?

huangapple 未分类评论55阅读模式
英文:

How to deactivate jnativehook on demand?

问题

如果我理解正确,jnativehook 可以使用以下两个命令来打开和关闭:

GlobalScreen.removeNativeKeyListener(this); // 关闭
GlobalScreen.addNativeKeyListener(this);    // 打开

按照这个逻辑,以下程序:

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

import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;

public class GlobalKeyListenerExample implements NativeKeyListener {

    public void nativeKeyPressed(NativeKeyEvent e) {
        System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
        String s = NativeKeyEvent.getKeyText(e.getKeyCode());
        handle(s);

        Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
        logger.setLevel(Level.OFF);
        logger.setUseParentHandlers(false);

        if (e.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
            try {
                GlobalScreen.unregisterNativeHook();
            } catch (NativeHookException ex) {
                ex.printStackTrace();
            }
        }
    }

    public void nativeKeyReleased(NativeKeyEvent e) {
    }

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

    public void handle(String k) {
        if (k.equals("A")) { // 关闭 nativeKeylistener 并执行 run()
            GlobalScreen.removeNativeKeyListener(this);
            run();
            run2(); // 打开 keylistener
        }
    }

    public void run() {
        System.out.println("Hello there!");
        System.out.print("Write something, please: ");
        Scanner lukija = new Scanner(System.in);
        String str = lukija.nextLine();
        System.out.println("you wrote: " + str);
    }

    public void run2() {
        GlobalScreen.addNativeKeyListener(this);
    }

    public static void main(String[] args) {
        Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
        logger.setLevel(Level.OFF);
        logger.setUseParentHandlers(false);

        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);
        }

        GlobalScreen.addNativeKeyListener(new GlobalKeyListenerExample());
    }
}

根据我的理解应该会打印出类似以下的内容:

Key Pressed: K
Key Pressed: J
Key Pressed: G
Key Pressed: U
Key Pressed: Y
Key Pressed: T
Key Pressed: H
Key Pressed: V
Key Pressed: B
Key Pressed: N
Key Pressed: H
Key Pressed: G
Key Pressed: A
Hello there!
Write something, please: i am a robot
you wrote: i am a robot

但实际上你得到了不同的结果。可能的原因是 NativeKeyListener 的特性。即使你在 handle 方法中移除了监听器,之前已经按下的按键事件仍然会被记录下来并传递给监听器。当你重新添加监听器时,这些已记录的按键事件将被立即处理,从而导致了你观察到的行为。这可能是你看到按下 "Backspace"、"I"、"Space" 等按键的原因。如果你希望在重新添加监听器后不立即触发之前已记录的按键事件,可能需要采取额外的措施,例如清除事件队列等。

英文:

If my understanding serves me correct jnativehook can be turned on and off with these two commands:

> GlobalScreen.removeNativeKeyListener(this); //this shuts it down
>
> GlobalScreen.addNativeKeyListener(this);//and this turns it back on again

by this logic the program below:

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

import java.util.Scanner; 
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;


public class GlobalKeyListenerExample implements NativeKeyListener {

public void nativeKeyPressed(NativeKeyEvent e) {


    System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
    String s = NativeKeyEvent.getKeyText(e.getKeyCode());
    handle(s);
   



    Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
    logger.setLevel(Level.OFF);


    logger.setUseParentHandlers(false);
    if (e.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
        try {
            GlobalScreen.unregisterNativeHook();
        } catch (NativeHookException ex) {
            ex.printStackTrace();
        }
    }
}



public void nativeKeyReleased(NativeKeyEvent e) {
}

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






public void handle(String k) {
    if (k == "A") {//close nativeKeylistener and execute run()
        GlobalScreen.removeNativeKeyListener(this);
        run();
      
        run2();//turn keylistener back on
    }

}

public void run() {
    System.out.println("Hello there!");
    System.out.print("Write something, please: ");
    Scanner lukija = new Scanner(System.in);
    String str = lukija.nextLine();
    System.out.println("you wrote: "+str);
}

public void run2() {
    GlobalScreen.addNativeKeyListener(this);

}





public static void main(String[] args) {
    Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
    logger.setLevel(Level.OFF);


    logger.setUseParentHandlers(false);
    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);
    }

    GlobalScreen.addNativeKeyListener(new GlobalKeyListenerExample());
}

}

It should print something like this, by my understanding.

kKey Pressed: K
Key Pressed: J
jKey Pressed: G
gKey Pressed: U
uKey Pressed: Y
yKey Pressed: T
tKey Pressed: H
hKey Pressed: V
vKey Pressed: B
bKey Pressed: N
nKey Pressed: H
hKey Pressed: G
gKey Pressed: A
Hello there!
Write: i am a robot
i am a robot

Instead i get this:

kKey Pressed: K
Key Pressed: J
jKey Pressed: G
gKey Pressed: U
uKey Pressed: Y
yKey Pressed: T
tKey Pressed: H
hKey Pressed: V
vKey Pressed: B
bKey Pressed: N
nKey Pressed: H
hKey Pressed: G
gKey Pressed: A
Hello there!
Write: i am a robot
i am a robot
Key Pressed: Backspace
Key Pressed: I
Key Pressed: Space
Key Pressed: A
Hello there!
Write: test
test
Key Pressed: M
Key Pressed: Space
Key Pressed: A
Hello there!
Write: test
test
Key Pressed: Space
Key Pressed: R
Key Pressed: O
Key Pressed: B
Key Pressed: O
Key Pressed: T
Key Pressed: Enter
Key Pressed: T
Key Pressed: E
Key Pressed: S
Key Pressed: T
Key Pressed: Enter
Key Pressed: T
Key Pressed: E
Key Pressed: S
Key Pressed: T

What happens is that nativehook keeps rergistering all the inputs even tho i have used the command

> GlobalScreen.removeNativeKeyListener(this);

and when i add it back it with run2(), the program goes through all the key presses i gave it while giving input(and the methods they invoke, in this case run() when "a" is pressed). Why this behavior?

答案1

得分: 0

你移除了键盘监听器,但这并不会阻止该库记录按键操作。

要停止记录,您应该执行以下操作:

GlobalScreen.unregisterNativeHook();
英文:

You remove the key listener but that doesn't stop the library from logging keystrokes.

To stop logging you shall do:

GlobalScreen.unregisterNativeHook();

huangapple
  • 本文由 发表于 2020年3月15日 23:58:38
  • 转载请务必保留本文链接:https://java.coder-hub.com/60694783.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定