Java jnativehook 输入字符串无效
Java jnativehook typing a string not working
我想在键入 ALT+A 时键入:“/ammo”。
该程序运行但似乎在 运行 之后立即停止:
我按 alt+A 或 A,代码什么也没做。
package jnativehook01;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
public class Example implements NativeKeyListener {
public void nativeKeyPressed(NativeKeyEvent e) {
if (NativeKeyEvent.getKeyText(e.getKeyCode()).equals("A")) {
try {
GlobalScreen.unregisterNativeHook();
Robot bot;
try {
bot = new Robot();
String text = "/ammo";
StringSelection stringSelection = new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
//type: /ammo
bot.keyPress(KeyEvent.VK_T);
bot.keyRelease(KeyEvent.VK_T);
} catch (AWTException e1) {
}
} catch (NativeHookException e1) {
}
}
}
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyTyped(NativeKeyEvent e) {
System.out.println("Key Typed: " + e.getKeyText(e.getKeyCode()));
}
public static void main(String[] args) {
new Example();
}
}
好的,现在可以使用了:
package jnativehook01;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
import java.util.logging.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
public class Example implements NativeKeyListener {
public void nativeKeyPressed(NativeKeyEvent e) {
if (NativeKeyEvent.getKeyText(e.getKeyCode()).equals("A")) {
Robot bot;
try {
String text = "/ammo";
StringSelection stringSelection = new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
bot = new Robot();
for (int i = 0; i < 10; i++) {
//t
bot.keyPress(KeyEvent.VK_T);
bot.delay(100);
bot.keyRelease(KeyEvent.VK_T);
bot.delay(500);
bot.keyPress(KeyEvent.VK_CONTROL);
bot.keyPress(KeyEvent.VK_V);
bot.keyRelease(KeyEvent.VK_V);
bot.keyRelease(KeyEvent.VK_CONTROL);
bot.delay(500);
//Enter
bot.keyPress(KeyEvent.VK_ENTER);
bot.keyRelease(KeyEvent.VK_ENTER);
bot.delay(1000);
bot.keyPress(KeyEvent.VK_ENTER);
bot.keyRelease(KeyEvent.VK_ENTER);
bot.delay(400);
}
} catch (AWTException e1) {
}
}
}
public void nativeKeyReleased(NativeKeyEvent e) {
}
public void nativeKeyTyped(NativeKeyEvent e) {
}
public static void main(String[] args) {
Example ex = new Example();
try {
GlobalScreen.registerNativeHook();
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.OFF);
} catch (NativeHookException eb) {
System.out.println(eb.getMessage());
}
GlobalScreen.addNativeKeyListener(ex);
}
}
您的代码仍有一些问题。
if (NativeKeyEvent.getKeyText(e.getKeyCode()).equals("A")) {
这不是检查 A 密钥的正确方法。这将检查 AWT 是否为该键生成 ascii 'A'。这些值可以在运行时被 JVM 覆盖。您应该检查 NativeKeyEvent.VK_A 常量。您也无法检查该键事件上的 ALT 标志。类似下面的内容更符合您的要求。
if (e.getKeyCode() == NativeKeyEvent.VC_A && e.getModifiers() & NativeInputEvent.ALT_MASK) {
关于线程安全的说明。您在键回调中依赖 AWT,但是,该库默认情况下不使用 AWT 来分派事件。您需要查看 wiki 的 Thread Safety 部分以获取线程安全示例。
为了方便,您可以选择将Robots
class替换为GlobalScreen.postNativeEvent(...)
,以省略Swing/AWT,但这不是必需的。
关于在事件侦听器回调内部阻塞的注意事项。如果您在该函数内部阻塞,通过睡眠或其他长 运行 进程,您可能会导致延迟在由 OS 或更糟的关键事件传递中,库被某些操作系统删除。此删除不在库的控制范围内,由 OS.
控制
我想在键入 ALT+A 时键入:“/ammo”。 该程序运行但似乎在 运行 之后立即停止: 我按 alt+A 或 A,代码什么也没做。
package jnativehook01;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
public class Example implements NativeKeyListener {
public void nativeKeyPressed(NativeKeyEvent e) {
if (NativeKeyEvent.getKeyText(e.getKeyCode()).equals("A")) {
try {
GlobalScreen.unregisterNativeHook();
Robot bot;
try {
bot = new Robot();
String text = "/ammo";
StringSelection stringSelection = new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
//type: /ammo
bot.keyPress(KeyEvent.VK_T);
bot.keyRelease(KeyEvent.VK_T);
} catch (AWTException e1) {
}
} catch (NativeHookException e1) {
}
}
}
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyTyped(NativeKeyEvent e) {
System.out.println("Key Typed: " + e.getKeyText(e.getKeyCode()));
}
public static void main(String[] args) {
new Example();
}
}
好的,现在可以使用了:
package jnativehook01;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.keyboard.NativeKeyEvent;
import org.jnativehook.keyboard.NativeKeyListener;
import java.util.logging.*;
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;
import java.awt.event.InputEvent;
public class Example implements NativeKeyListener {
public void nativeKeyPressed(NativeKeyEvent e) {
if (NativeKeyEvent.getKeyText(e.getKeyCode()).equals("A")) {
Robot bot;
try {
String text = "/ammo";
StringSelection stringSelection = new StringSelection(text);
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(stringSelection, stringSelection);
bot = new Robot();
for (int i = 0; i < 10; i++) {
//t
bot.keyPress(KeyEvent.VK_T);
bot.delay(100);
bot.keyRelease(KeyEvent.VK_T);
bot.delay(500);
bot.keyPress(KeyEvent.VK_CONTROL);
bot.keyPress(KeyEvent.VK_V);
bot.keyRelease(KeyEvent.VK_V);
bot.keyRelease(KeyEvent.VK_CONTROL);
bot.delay(500);
//Enter
bot.keyPress(KeyEvent.VK_ENTER);
bot.keyRelease(KeyEvent.VK_ENTER);
bot.delay(1000);
bot.keyPress(KeyEvent.VK_ENTER);
bot.keyRelease(KeyEvent.VK_ENTER);
bot.delay(400);
}
} catch (AWTException e1) {
}
}
}
public void nativeKeyReleased(NativeKeyEvent e) {
}
public void nativeKeyTyped(NativeKeyEvent e) {
}
public static void main(String[] args) {
Example ex = new Example();
try {
GlobalScreen.registerNativeHook();
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.OFF);
} catch (NativeHookException eb) {
System.out.println(eb.getMessage());
}
GlobalScreen.addNativeKeyListener(ex);
}
}
您的代码仍有一些问题。
if (NativeKeyEvent.getKeyText(e.getKeyCode()).equals("A")) {
这不是检查 A 密钥的正确方法。这将检查 AWT 是否为该键生成 ascii 'A'。这些值可以在运行时被 JVM 覆盖。您应该检查 NativeKeyEvent.VK_A 常量。您也无法检查该键事件上的 ALT 标志。类似下面的内容更符合您的要求。
if (e.getKeyCode() == NativeKeyEvent.VC_A && e.getModifiers() & NativeInputEvent.ALT_MASK) {
关于线程安全的说明。您在键回调中依赖 AWT,但是,该库默认情况下不使用 AWT 来分派事件。您需要查看 wiki 的 Thread Safety 部分以获取线程安全示例。
为了方便,您可以选择将Robots
class替换为GlobalScreen.postNativeEvent(...)
,以省略Swing/AWT,但这不是必需的。
关于在事件侦听器回调内部阻塞的注意事项。如果您在该函数内部阻塞,通过睡眠或其他长 运行 进程,您可能会导致延迟在由 OS 或更糟的关键事件传递中,库被某些操作系统删除。此删除不在库的控制范围内,由 OS.
控制