How to use PC keyboard during Remote Screen Sharing using Android app? - java

We have a remote screen sharing option in our android app for Android TV devices. We use OEM API to trigger some of the key and button events by passing the constants defined in the android.view.KeyEvent class. This works for number keys and cursor keys in keyboard but the KeyEvent constants for alphabets are limited to only uppercase letters, like KEYCODE_A for 'A' key. There are no constants for smallercase letters.
Tried using input text command. It works in the shell but doesn't work in the app -
String keyCommand = "input text " + character;
Runtime runtime = Runtime.getRuntime();
Process proc = runtime.exec(keyCommand);
int waitFor = proc.waitFor();
Exit value returned is 1.
Is there any other way to process the Uppercase and lowercase letters events received from a Keyboard?
Edit: We are not using the KeyEvent class methods or constants directly as the input is not from a physical keyboard but from the keyboard of the PC in which the remote screen is viewed. Only the KeyEvent constant values are passed to OEM API for triggering the key/button.

Related

Ignore input method input in AWT Component on Mac

On Mac, the US International PC keyboard layout has dead keys for several keys such as ", ' and backtick. When typing ", the Mac starts input method composition - the " shown in compose mode (usually underlined) and waits for further input. If I use a, then the input method will complete and I'll get the character ä. There are several such dead keys, and e.g. the British keyboard layout treats Alt+n as a dead key to give something like ñ.
In a Java AWT application, is there any way I can disable this behaviour so that I get simply the raw keys typed? E.g. in the US International PC keyboard layout, if I type "+a, I want to receive events for " and a, and not one event for ä. In the British keyboard layout, I want to type Alt+n+n and receive events for Alt+n and n and not ñ.
If I call Component.enableInputMethods(false), then my event queue will receive the Alt+n event, but if I then follow with n, I receive ñ.
Similarly, if I use a Chinese keyboard layout, the popup input method is still active, even after calling Component.enableInputMethods(false).
Is there any way to completely disable input method processing, and receive just the keys, as typed?
For context, I'm trying to implement Vim like behaviour - normal mode editing requires ASCII input, while insert mode will of course handle input methods as expected. While it would be ideal to swap to an ASCII keyboard layout in normal mode, but even the Mac's "ABC" keyboard layout has dead keys for Alt+n, Alt+u, Alt+I and Alt+e and Alt+Backtick. Telling users to create a custom keyboard layout with something like Ukulele is not a viable option.

JavaFX KeyEvent - Is it possible to get more info for Undefined Events?

I'm trying to register global hotkeys directly with the operating system for my program. I have it working for all keys that are listed as a JavaFX KeyCode, but if the KeyCode is "Undefined" for a particular key, I am not able to distinguish it from other undefined keys, so I can't use it.
OS: xubuntu 18.04.
Java: Version 11.0.1 2018-10-16 LTS, Oracle
JavaFX: SDK 11.0.1
A good example are the "Media Keys" that are located on many keyboards.
When I press a media key on my keyboard, I get an undefined KeyEvent:
System.out.println(keyEvent): Key Event: KeyEvent [source = TextField#25181b05[styleClass=text-input text-field], target = TextField#25181b05[styleClass=text-input text-field], eventType = KEY_PRESSED, consumed = true, character =
keyEvent.getCode(): UNDEFINED
I would like to be able to recognize if that key is pressed again. I don't need to know what the name of the key is. I just need to know the next time that unique key is pressed and react.
The problem is that I don't see any way to differentiate between UNDEFINED keys in KeyEvent in JavaFX. Based on the public API of KeyEvent and by looking at the source code of KeyEvent in JavaFX, it seems like KeyEvent does not keep any additional information that can uniquely identify a key press that is Undefined in KeyCode.
Digging deeper into the JavaFX code, it appears the unique identifier I need might be present in the method EmbeddedScene.keyEvent:
#Override
public void keyEvent(final int type, final int key, final char[] ch, final int modifiers);
That argument final int key is passed to a KeyCodeMap.valueOf (key) function, which, in this case, returns KeyCode.UNDEFINED. I can't easily test, but I'd bet that that int has different values for each of these different media keys.
is there any way to listen for KeyEvents at a lower level on a JavaFX stage -- before they get converted into a KeyCode and the information I need is lost -- so I can catch the hotkey and register it with the operating system?
I'm confident that if I can just get a method in my code base to fire when a key is pressed, and have that key show a unique identifer, I can wire the rest of the parts together. It doesn't necessarily need to be in the JavaFX stack.

Can I simulate game pad button presses with Java's Robot class (Java.awt.robot)?

I'm using an Arduino Uno to hook a (genuine) SNES controller to a computer via USB or Bluetooth.
The Arduino captures the controller's button presses and releases using the snespad library. It communicates button presses and releases as characters (e.g. 'a' for pressing A, 'A' for releasing 'A'). Next, a Java program listens to the serial output using the rxtx library. Finally, a Java robot simulates key presses using the keyPress and keyRelease.
Unfortunately, this approach has a few drawbacks. The main issue is key mapping. I kind of arbitrarily decided which buttons would be which keyboard keys.
Java doesn't appear to have any game pad KeyEvents. When I say "game pad KeyEvent," I mean something like what the Android SDK has: http://developer.android.com/reference/android/view/KeyEvent.html (ctrl+f "game pad" or "button".)
My question is, is there a way to simulate game pad button presses instead of keystrokes using Java's robot class?
USING THE ROBOT CLASS IN JAVA
You can create virtual keypresses/releases in the following way...
Robot robo=new Robot();
robo.keyPress(KeyEvent.VK_A);
//don't forget to release it else you'll land up in infinite loop
robo.KeyRelease(KeyEvent.VK_A);
cheers
You should be able to easily from my expierience the gamepad buttons are mapped to keyboard buttons the only mapping i know it i,j,k,l go to looking around and w,a,s,d go to moving around

How to simulate keyboard input (including cursor movement) by programmatically generating KeyEvents

I am trying to simulate keyboard input by programmatically generating KeyEvent objects and pumping them to the event queue. This works fine except that when characters are being entered into a JTextField, for example, the cursor (caret?) does not move to always be at the end of the entered value. For example, if we denote the caret as the pipe | then this is what I get:
An 'A' keypress is simulated by sending a KEY_PRESSED, KEY_TYPED, KEY_RELEASED event, and the JTextField value is:
|A
that is, the cursor/caret is back at the beginning of the field after the A is entered.
How do I get the cursor/caret to automatically move as it would when actual physical keys are pressed?
Have you tried using the Robot Class in the JDK?
http://docs.oracle.com/javase/6/docs/api/java/awt/Robot.html
After you issue each command, call a method that uses setCaretPosition() to the end of the text in the JTextField. This will be much easier if you use a J*Pane so you can call getDocument() and you will have much more control.

Why are some KeyEvent keycodes throwing "IllegalArgumentException: Invalid key code"?

I'm trying to automate some processes using Robot and it seems certain keycodes (only symbols that require you to hold shift when typing it normally) in KeyEvent are throwing an IllegalArgumentException. This is all the code that's running in main:
Robot r = new Robot();
r.keyPress(KeyEvent.VK_EXCLAMATION_MARK);
However, it works fine using the following workaround:
Robot r = new Robot();
r.keyPress(KeyEvent.VK_SHIFT);
r.keyPress(KeyEvent.VK_1);
Any ideas why the exception is thrown? Thanks!
Java version: 1.6.0_23
Because like the documentation for Robot.keyPress says, an IllegalArgumentException is thrown when the keycode doesn't represent a valid key, and VK_EXCLAMATION_MARK is not a valid key.
Keycodes are used to represent two things: keys on the keyboard, and "a character was typed" events. Typing a character often requires more than one keypress (in sequence, or simultaneously, or both). But Robot.keyPress simulates the act of pressing a key (hence the name), not the act of typing a character.
For more information, see the documentation for KeyEvent: http://download.oracle.com/javase/6/docs/api/java/awt/event/KeyEvent.html
I don't know Robot, but isn't that because it needs to be two keys pressed to an exclamation mark to be inserted.
There are no exclamation mark key on the keyboards.

Categories