I register
getInputMap().put(KeyStroke.getKeyStroke("pressed RIGHT"), "go right");
When testing the code I get: While I hold the right arrow key down, the action is triggered repeatedly and not only once as I would have expected this.
Interestingly
getInputMap().put(KeyStroke.getKeyStroke("released RIGHT"), "stop");
triggers stop only when the key is finally released.
Is there a way to register a key stroke on an input map, so that the associated action is only triggered once at the moment when the key is pressed?
KeyStroke: InputMap and Keymap maps one KeyStroke object to a action name or action. KeyStroke class is a member of javax.swing package and any object of this class represents a key or a combination of keys in the keyboard. 2.
A KeyStroke represents a key action on the keyboard, or equivalent input device. KeyStrokes can correspond to only a press or release of a particular key, just as KEY_PRESSED and KEY_RELEASED KeyEvents do; alternately, they can correspond to typing a specific Java character, just as KEY_TYPED KeyEvents do.
KeyStroke class is a member of javax.swing package and any object of this class represents a key or a combination of keys in the keyboard. 2. Technologies Used
In all cases, KeyStrokes can specify modifiers (alt, shift, control, meta, altGraph, or a combination thereof) which must be present during the action for an exact match. KeyStrokes are used to define high-level (semantic) action events.
Documentation of KeyStroke:
A KeyStroke represents a key action on the keyboard, or equivalent input device. KeyStrokes can correspond to only a press or release of a particular key, just as KEY_PRESSED and KEY_RELEASED KeyEvents do; alternately, they can correspond to typing a specific Java character, just as KEY_TYPED KeyEvents do. In all cases, KeyStrokes can specify modifiers (alt, shift, control, meta, altGraph, or a combination thereof) which must be present during the action for an exact match.
To trigger the event only once, at release time, I suggest to register
getInputMap().put(KeyStroke.getKeyStroke("typed RIGHT"), "go right");
The documentation of KeyStroke.getKeyStroke(String) is:
Parses a string and returns a KeyStroke. The string must have the following syntax:
modifiers* (typedID | pressedReleasedID) modifiers := shift | control | ctrl | meta | alt | altGraph typedID := typed <typedKey> typedKey := string of length 1 giving Unicode character. pressedReleasedID := (pressed | released) key key := KeyEvent key code name, i.e. the name following "VK_".
To trigger the event only once, at press time, I suggest to register the press and release events to manage yourself a latch with a boolean.
Is there a way to register a key stroke on an input map, so that the associated action is only triggered once at the moment when the key is pressed?
Remove the keyPressed binding from the InputMap. Then for the keyReleased Action you add the keyPressed binding back to the InputMap.
However, even this can cause problems because on a Windows OS the sequence of KeyEvents is:
pressed, pressed, pressed.... released.
This makes sense to me as generally when you hold the key down you want the character to repeat. However, on a Mac I believe the sequence is:
pressed, released, pressed, released, pressed, released
which doesn't make sense to me and makes it difficult to determine when a key has truly been released.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With