Is it possible to emit the numpad arrow key in Java? - java

Background
Operating systems (I'm on Windows 10, if it matters) have a feature called Mouse Keys that allow you to perform the operations of the mouse using the numpad. Press 5 to click, 8/2/4/6 to move the cursor up/down/left/right, and so on.
The Desire
I would like to move the cursor around when Mouse Keys is activated, programmatically, in Java. I specifically want to use keyboard events for this, as moving the mouse directly is verboten in the context I'm in.
The Problem
I tried using Robot.keyPress and Robot.keyRelease with keycode KeyEvent.VK_KP_UP = 224, but that yields the following error:
java.lang.IllegalArgumentException: Invalid key code
at java.desktop/sun.awt.windows.WRobotPeer.keyPress(Native Method)
at java.desktop/java.awt.Robot.keyPress(Robot.java:350)
And trying it with KeyEvent.VK_NUMPAD8 doesn't error out, but also doesn't make the mouse move.
I also tried jnativehook's GlobalScreen.postNativeEvent(new NativeKeyEvent(...)), and no amount of voodoo could get it to work either. There's no constant in NativeKeyEvent for the keypad up key, so that's not super surprising. When I try to send the keycode 224, the following error occurs:
com.github.kwhat.jnativehook.GlobalScreen postNativeEvent
WARNING: map_keyboard_event [97]: Unable to lookup scancode: 224
Am I asking the impossible?

Related

How to distinguish left and right mouse buttons in JavaFX?

I'm making a toy hearing test application with Java8 (I'm using JavaFX version 8).
In order to assess if the user can hear the sound he has to click on a UI button with the mouse button which corresponds to the side the sound was coming from.
So, in the click event, I need to distinguish between right and left click buttons, but all JFX seems to be giving me is
PRIMARY
Represents primary (button 1, usually the left) mouse button.
SECONDARY
Represents seconday (button 3, usually the right) mouse button.
which is clearly not good enough: stereo channels aren't going to be inverted only because the user is left-handed.
So, is there any way to tell if PRIMARY is the left or right mouse button?
PS: I can obviously solve the problem by explicitly asking the user to right-click and left-click before starting. I'd like to know if it's possible to avoid that.
I've been browsing through the API and Microsoft docs. The primary and secondary mousebuttons have no unique name - as far as I'm aware of. I can't find a method in Java to find out whether the box "invert mousebuttons" is ticked off or not.
Creating a button "Click left to begin" could function as a "start" and primary mousebutton detection. Maybe there are Java libraries out there which provide a more flexibility using primary/secondary mouse buttons.

How Do the KeyEvent.VK_REDO and Similar Constants Work in an Accelerator?

I'm trying to create menu item accelerators for undo, redo, etc. in a Java application so I can access them with key commands. I also want to make it so that the proper key command appears on the proper platform. For some menu items, like "Undo", it's pretty simple because it's Cmd/Ctrl+Z:
this.undoMenuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
The method getMenuShortcutKeyMask() returns the Cmd key on a Mac and the Ctrl key on a Windows machine. So far so good.
But some menu items have drastically different key combinations on different platforms. To Redo on Mac OS, you do Cmd+Shift+Z, but on Windows you do Ctrl+Y. Thus the above code won't work unless you do an if/then statement to check what platform you are on and pass one of two sets of parameters into the function.
I noticed that in the KeyEvent class are constants such as KeyEvent.REDO. I'm presuming that this is a constant for the "Redo" key combination, although I'm not sure because there isn't any documentation about what it does. So I tried the following:
this.redoMenuItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_REDO, 0));
I had hoped that this would result in the appropriate key combination applied as an accelerator, but instead no accelerator appears to be assigned (i.e. there isn't any indicator of the key combination next of the name of the menu item). Is this the proper use of KeyEvent.VK_UNDO and if so, what am I doing wrong?

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.

J2ME Combo key press (multiple keys at once)

I am using keyboard_key variable from here:
//overrides the function keyPressed from "lcdui.Canvas"
protected void keyPressed(int keyCode){
keyboard_key = keyCode;
}
to detect if any key was pressed on a mobile phone.
But it returns only the key that is pressed most lately and it doesn't tell if any other key might be pressed. Please help!
Btw, I'm using NetBeans 7.0.1 as IDE.
...it returns only the key that is pressed most lately and it doesn't tell if any other key might be pressed
The way you use it in your code snippet, keyboard_key will always contain only the key that is pressed most lately - just because it "has no room" to hold anything more than that.
Consider using Vector to "memorize" different keys that were pressed.
//define in your class:
Vector keysPressed = new Vector(); // to keep track of keys pressed
//overrides the function keyPressed from "lcdui.Canvas"
protected void keyPressed(int keyCode){
keysPressed.addElement(new Integer(keyCode));
}
Side note given the question, you may benefit from studying Java language basics. There are many tutorials available online - just search the web for something like "Java getting started".
Depending on your application requirements, consider overriding keyRepeated along with keyPressed.
If you intend to handle key presses in game-loop fashion ("multiple keys at once" suggest that you may possibly have this in mind), consider another option provided by lcdui.game.GameCanvas API, method getKeyStates():
Gets the states of the physical game keys. Each bit in the returned integer represents a specific key on the device. A key's bit will be 1 if the key is currently down or has been pressed at least once since the last time this method was called. The bit will be 0 if the key is currently up and has not been pressed at all since the last time this method was called. This latching behavior ensures that a rapid key press and release will always be caught by the game loop, regardless of how slowly the loop runs...

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