Block user input and postNativeEvent
Zhemaitis opened this issue · 4 comments
Hello, I don't know if this is the right place to ask questions, but I am stuck. Currently, I am working on a keybinding program. The program should work like this - if a user presses a specific keyboard button it should output something else. In my sample code, if the user presses the keyboard button G it should output 9. The problem now is that it outputs G9, so the question is if there is a way to block that user pressed the keyboard button to be outputed (in this case letter G)?
Thank you for your help and tips
public class GlobalKeyListenerExample implements NativeKeyListener {
public void nativeKeyPressed(NativeKeyEvent e) {
System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()) + " " + NativeKeyEvent.getKeyText(e.getRawCode()));
int someKeyCode = KeyEvent.VK_G;
Object someKeyCodeObject = new Integer(someKeyCode);
String keyString = KeyEvent.getKeyText((Integer) someKeyCodeObject);
System.out.println(NativeKeyEvent.getKeyText(e.getKeyCode()));
if (NativeKeyEvent.getKeyText(e.getKeyCode()).equalsIgnoreCase(keyString)) {
NativeKeyEvent ev = new NativeKeyEvent(
NativeKeyEvent.NATIVE_KEY_PRESSED,
0x00,
0x00,
NativeKeyEvent.VC_9,
NativeKeyEvent.CHAR_UNDEFINED);
GlobalScreen.postNativeEvent(ev);
}
if (e.getKeyCode() == NativeKeyEvent.VC_ESCAPE) {
try {
GlobalScreen.unregisterNativeHook();
} catch (NativeHookException nativeHookException) {
nativeHookException.printStackTrace();
}
}
}
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) {
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());
}
}
Best regards,
-zhemaitis
so the question is if there is a way to block that user pressed the keyboard button to be outputed (in this case letter G)?
If you are using this on Windows or Mac OS, you can prevent event propagation is most cases. Notice, you must use a VoidDispatchService, one currently exists in the 2.2 codebase so the docs need updating.
After code execution, an exception appears. Googled this problem and it sounds like illegal action was performed. Is there a way to solve this problem right now?
java.lang.reflect.InaccessibleObjectException: Unable to make field private short com.github.kwhat.jnativehook.NativeInputEvent.reserved accessible: module com.github.kwhat.jnativehook does not "opens com.github.kwhat.jnativehook" to module NativeKeyListener
IDK what you did, the example compiles on works for me. I updated the markdown file to use the inertial void dispatcher.
import com.github.kwhat.jnativehook.GlobalScreen;
import com.github.kwhat.jnativehook.NativeHookException;
import com.github.kwhat.jnativehook.NativeInputEvent;
import com.github.kwhat.jnativehook.dispatcher.VoidDispatchService;
import com.github.kwhat.jnativehook.keyboard.NativeKeyEvent;
import com.github.kwhat.jnativehook.keyboard.NativeKeyListener;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.AbstractExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ConsumeEvent implements NativeKeyListener {
public ConsumeEvent() throws NativeHookException {
// Create custom logger and level.
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.WARNING);
GlobalScreen.setEventDispatcher(new VoidDispatchService());
GlobalScreen.registerNativeHook();
GlobalScreen.addNativeKeyListener(this);
}
public void nativeKeyPressed(NativeKeyEvent e) {
if (e.getKeyCode() == NativeKeyEvent.VC_B) {
System.out.print("Attempting to consume B event...\t");
try {
Field f = NativeInputEvent.class.getDeclaredField("reserved");
f.setAccessible(true);
f.setShort(e, (short) 0x01);
System.out.print("[ OK ]\n");
NativeKeyEvent ev = new NativeKeyEvent(
NativeKeyEvent.NATIVE_KEY_PRESSED,
0x00,
0x00,
NativeKeyEvent.VC_9,
NativeKeyEvent.CHAR_UNDEFINED);
GlobalScreen.postNativeEvent(ev);
}
catch (Exception ex) {
System.out.print("[ !! ]\n");
ex.printStackTrace();
}
}
}
public void nativeKeyReleased(NativeKeyEvent e) {
if (e.getKeyCode() == NativeKeyEvent.VC_B) {
System.out.print("Attempting to consume B event...\t");
try {
Field f = NativeInputEvent.class.getDeclaredField("reserved");
f.setAccessible(true);
f.setShort(e, (short) 0x01);
System.out.print("[ OK ]\n");
NativeKeyEvent ev = new NativeKeyEvent(
NativeKeyEvent.NATIVE_KEY_RELEASED,
0x00,
0x00,
NativeKeyEvent.VC_9,
NativeKeyEvent.CHAR_UNDEFINED);
GlobalScreen.postNativeEvent(ev);
}
catch (Exception ex) {
System.out.print("[ !! ]\n");
ex.printStackTrace();
}
}
}
public void nativeKeyTyped(NativeKeyEvent e) { /* Unimplemented */ }
public static void main(String [] args) throws NativeHookException {
new ConsumeEvent();
}
}
After code execution, an exception appears. Googled this problem and it sounds like illegal action was performed. Is there a way to solve this problem right now?
java.lang.reflect.InaccessibleObjectException: Unable to make field private short com.github.kwhat.jnativehook.NativeInputEvent.reserved accessible: module com.github.kwhat.jnativehook does not "opens com.github.kwhat.jnativehook" to module NativeKeyListener
You are using Java modules and/or run Java with forbidden illegal access. Look into module system. You can fix this by adding the appropriate add-opens
JVM argument.