In a swing program I am trying to receive input specifically from the num pad keys on the keyboard using key bindings.
myPanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD8, 0), “numpad8”);
myPanel.getActionMap().put(“numpad8”, numPad8);
Works fine if I got the num lock on, which is as expected, however if I add:
myPanel.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_KP_UP, 0), “numpad8”);
Without num lock on, my keyboard does not cause numPad8 Action to be called (in fact it seems to generate KeyEvent.VK_UP instead). This is surprising to me as the documentation of KeyEvent specifies that KeyEvent.VK_UP is
Constant for the non-numpad up arrow key.
and KeyEvent.VK_KP_UP
Constant for the numeric keypad up arrow key.
So my question is: If I want my code to support as many keyboard set ups as possible what KeyEvents should I expect from the num pad? Should I add KeyEvent.VK_8 to the above just be safe, for example?
Related
I'm currently working on the input system of a game engine in java, and I use GLFW for the window. I set up a callback system to catch when a key is pressed:
GLFW.glfwSetKeyCallback(window, (windowId, key, scancode, action, mods) -> {
if (action == GLFW.GLFW_PRESS) {
System.out.println(GLFW.glfwGetKeyName(key, scancode));
}
});
And the problem is when I press space or enter or shift plus a different key it prints out null. My question is: how to use the mods attribute to capitalize the next key when I press shift or print out a new line when I press enter etc.
I don't know the solution for the first question, but the second one is easy.
Try using char callback. This one is different from key callback, as it only works with unicode characters being typed by user (letters are capitalized with Shift, CapsLock button also works). Also, if you want to detect modifier buttons being pressed while user types, try using charMods callback. Seems like the latter is marked for removal, so you can test whether the modifier button is pressed with glfwGetKey().
EDIT: Seems like I didn't understood you on the first one. glfwGetKeyName() is not designed to be used as text input method. Also note that it can display names for a limited range of buttons. What is more, when you press multiple keys, press event for each one is called in separate key callback event. You can't handle multiple key presses at once. (Modifier keys are put in mods argument of callback, but I can't tell by now whether they also trigger a key press event or not - check it yourself)
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.
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.
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...
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.