Java block keyboard presses - java

Is there a way how to block keyboard input in java. I would like to catch the input in the java code, but stop it from being send to OS.
Example: i have notepad opened and i can write just fine, but when i press a combination of keys java app catches that input, and now i should not be able to write with my keyboard. Is this kind of behaviour possible?
I know how to capture key presses but the keyboard blocking part is a mystery to me.
I tried googling it but i did not find any solution.

You have to understand: java applications run with the JVM. A JVM isn't the operating system.
Therefore your ways to access resources belonging to the operating system are very limited.
In other words: there is no generic, cross plattform way of having a Java application being able to "intersect" arbitrary console user input for arbitrary other applications.
Imagine you are a person sitting in a bus - just a guy like everybody else. You have no authority to turn to fellow passengers and ask them for their passport or such things. You are just one guy in the bus, like everybody else. Same here: a Java application is lacking the means to control other processes.
As you are specifically asking about the Windows platform: there might be some options using JNI and specific native calls. See here for example.
So, to be precise: it is not possible in general, but depending on your operating system there might be ways, for example using JNI.

Yes, you can do this - I used this library:
https://github.com/tulskiy/jkeymaster
to successfully to register a "global" keyboard shortcut to open a window in my program that was running in the task tray.
You can't "stop" it from being sent to the OS, but you can register a keyboard shortcut, open your window, and give it focus, so that all other keystrokes go into that text box.

Related

Capturing keyboard input from specific USB port

i'm stuck at capturing keyboard events.
I'm working with a barcode scanner which is detected by system as traditional keyboard (it is it's only mode, my client has a lot of budget scanners which can't emulate virtual com port).
My goal is to be able to detect at which port is this scanner plugged in, capture any input from that port, and prevent it from being handled by the OS (i don't want the barcode numbers popping up on focused input).
All this must be performed by a background service, which is never an active window, AND the solution must work both on linux and on windows.
I've been able to capture the input using jnativehook, but failed to prevent it from being handled by OS.
As far as i know, it is impossible to achieve this using pure java (JVM gives access to keyboard events only when application window is focused), so how should i handle this issue? I'm okay with using jni and c++ if that's necessary, but i don't know where to start.
JNativeHook does have the ability to discard events on Windows and OSX (not Linux), however, it does not have the ability to determine which USB port the scanner is connected to. The reason it cannot consume events on Linux is because the XRecord API makes a copy of the events and doesn't sit directly on the input event loop. If the devices you are working with can utilize HID, I would take a look into some of the JNI HID library wrappers like gary-rowe/hid4java or signal11/hidapi. The assertion that "it is impossible to achieve this using pure java" is correct. The only way to do it would be though native code, and HID is the most appropriate native method to accomplish your goals. Other input methods like input hooking (used by JNativeHook) will not be able to provide you with the source USB port, nor can they consume events on some platforms (Linux). There is another option out there like melloware/jintellitype that use a different mechanism for capturing input. I don't think it can grab input based on the port, however, the non-portable Linux equivalent of this library uses the XGrab API which will only consume events, but again, I don't know if it will be practical for your input source as I think it can only bind one key per call and that key must use a modifier.
Hope this helps you move forward with your project.

How to make sure the user does not able to do any other thing once my window is shown in linux/mac [duplicate]

How can I disable OS-level keyboard shortcuts (e.g. Alt-Tab, Ctrl-Alt-Left/Right, etc.) on a [Ubuntu] Linux machine? I'm developing a full-screen Java Swing app and don't want the user to be able to task switch away from the program arbitrarily. It's not enough to toggle the "always on top" flag; users mustn't be allowed to switch workspaces, migrate focus or any other such things. The machine must function normally before and after the application is executed. Google says that this will require JNI or JNA but I'm looking for a bit more hand-holding.
There's no point in trying to do this in your application because any of these changes are going to need to be handled by X11 and/or the window manager since those are what respond to the commands. Assuming that you have control of the platform, choose a window manager which supports a kiosk mode. Then use the window manager's settings to start your application and enter kiosk mode.
Options for window managers which can do this include KDE or twm-kiosk.
(And if you don't have control of the platform, you're not likely to be able to have your application intercept things like ctrl-alt-backspace anyway.)
Edit:
In response to a scaled-down version of the question in which he's willing to let things like ctl-alt-backspace go and just wants most of the keys including alt-tab or other similar application switching key combinations, the following should work:
You should be able to do this using XLib's XGrabKeyboard method through JNI. This Java/XLib JNI keypress capture tutorial should be a good starting point. However, it uses XGrabKey which just passively listens for keys and does not prevent other applications from receiving them. You'll instead want to use XGrabKeyboard which actively snags all of the normal keyboard events (which, if the premise of this StackOverflow question is correct, includes the task switching keys).
Note that as a side-effect, key capture in Swing will also probably stop working because your Swing windows are going to be separate from the window you create in C. As such, you will probably have to use your JNI interface to get key presses to your program when needed. (Although I would definitely advise testing it first before writing the code.) You might be able to avoid this if you can get the window using Java AWT Native Interface to get the window ID. (Note that Swing is built on top of AWT, so this will work for Swing.) However, I'm not sure how to do this. It looks like you might be able to navigate the window tree by getting the root window from the Display and going from there to find your Window, but it's all kind of weird. It would be nice if the AWT NI just told you the window ID, but it doesn't look like it does that.
As this warning Reminder: XGrabKeyboard is not a security interface notes, this doesn't make it impossible for other programs to see the keys, but it seems likely that window managers will not be using XQueryKeyMap so it is likely to prevent task switching.

How to send key-ins to certain windows

I'm looking to write a relatively simple key macro for my own edification and also for my own use.
I intend for it to be able to run in the background when I run other programs, and at the press of a button will enter certain text into the active window. To be more specific, I want to go in a video game and use it to automatically send messages instead of having to type them.
I Googled around a bit, but apparently I'm not using the right keywords because I'm not really sure where to start. The closest I came was finding the Keystroke class, but that appears to be used for receiving keystrokes, not sending them.
I would appreciate and info regarding, or directing me to a resource for, these issues (how to send keystrokes to windows and anything about targeting which window etc).
To send key strokes you can use java.awt.Robot
To Choose which window to activate you can look around for ws script (windows script) or old VB6 code and use it to make VB script (simple text file of extn .vbs)
Or you can junk all that and use http://www.autohotkey.com/ which has window activation, sending keys, doing things on press of certain keys (like Windows Key + B) or macros.
To get a window to activate I had made an exe long back, but no longer use it, can get it from http://sourceforge.net/projects/win-utils/files/Window-Position/rel%2001/ (but only get this if the others do not work as need to seperately get COMCTL32.ocx and install that
If you do not want to use autohotkey you can use Jini to call platform specific functions, with a wrapper to call correst OSes functions. Never done it my self, when i had to use it i would make a process to call a exe that made the window come the front.

Java input when window is not active

Is there a way to detect key input when the window is not active? That is, another application is running but the program is triggered when say the F9 key is pressed or something along those lines.
Is that possible or is java not compatible for such functions? From what I found java can't get input unless it's the active window.
Note:
I typically use keylistener, which seems to stop working (with good reason) when I am not actively using the program.
It sounds like you want low level keyboard hooks.
Get global keyboard input with Java
It's not directly possible in Java (i.e. with pure Java code), but you could reference other libraries (or make your own) to acheieve this. A quick google search gives a lot of references and free/open libraries that can give you keyboard and mouse hooks (both very handy).
Hope that helps.

Capture key stroke from separate process in Java

I want this to happen:
Start my java program
My java program launches notepad.exe
If I type a letter in notepad my java program should react and print out the letter
In short: Is it possible to make a key event listener for another process? The java program won't have focus.
If it's impossible I want to be able to change focus between my Java swing window and the notepad process. For example:
A) My java program has focus (small swing window), I type the letter "A"
B) Notepad is given focus quickly and the letter A is typed there (for example using the Robot class)
C) My java program gets focus again
Quoting the answer given in Creating a keyboard hook for a Java program that sits in the System Tray
so , creating a keyboard hook isn't as easy as it looks , java doesn't provide a direct way to interact with the system events for purposes of security ; as it might lead to serious problems concerning the JVM , system's memory and the portability of Java Framework..
you have 4 ways to make global keyboard hooks :
Learn JNI / JNA, and I prefer JNA since its much easier than JNI , in both cases you shall deal with .dll files.
Use JIntellitype , which - as you said - issues some problems.
the elegant solution by Sergei Biletnikov here http://biletnikov-dev.blogspot.com/2009/09/global-hotkeys-for-java-applications_25.html
ignore Java , and try Autoit V3 ( I'm not 100% sure about it , but I think you could send signals/events from Autoit to your Java app , so Autoit would just work as a bridge that catches the global key strokes)
Going with number 3, which is a good tutorial. If the link has 404'd maybe the project source is still up: gigapeta.com/dl/1917618aba749a
With your presented solution #1:
Learn JNI / JNA, and I prefer JNA since its much easier than JNI , in both cases you shall deal with .dll files.
You should take a look at this stackoverflow thread:
JNA Keyboard Hook in Windows
There is copy/pastable code that demonstrates a JNA key hook. You will need to download the JNA dependencies from http://jna.java.net/ for the example to work. You won't even need to fiddle with silly DLL's.
Additionally, you might want to give this library a try. While I have no experience with it, it popped up on my google search for "java keyboard hook." It seems to accomplish the goal of intercepting the keystrokes:
http://code.google.com/p/jnativehook/
Note that you would need some additional native code to see what the current "active window" is. If the active window matches "Notepad.exe" then you should record a native key event.
Good luck!

Categories

Resources