I'm writing a simple program in Java which includes a KeyListener with the following overriding they KeyTyped method:
@Override
public void keyTyped(KeyEvent e)
{
int key = e.getKeyCode();
System.out.println("TEST");
if (key == KeyEvent.VK_KP_LEFT || key == KeyEvent.VK_LEFT)
{
System.out.println("LEFT");
//Call some function
}
else if (key == KeyEvent.VK_KP_RIGHT || key == KeyEvent.VK_RIGHT)
{
System.out.println("RIGHT");
//Call some function
}
}
When I type anything other than the arrow keys (e.g. "a"), it prints TEST
as it should. However, when I type a numpad arrowkey, it only prints TEST
and when I type a standard arrow key it doesn't print anything at all. Is this possibly because I'm on a laptop, or have I just made a silly mistake somewhere?
The variables VK_UP , VK_DOWN , VK_LEFT , and VK_RIGHT represent the up, down, left, and right arrow key values respectively.
The keyPressed method is called when the user presses a key, the keyReleased method is called when the user releases a key, and the keyTyped method is called when the user types a character.
Press and release the Shift key. The text field fires two events: a key-pressed and a key-released. The text field doesn't fire a key-typed event because Shift, by itself, doesn't correspond to any character. Type an uppercase 'A' by pressing the Shift and A keys.
The KeyTyped() listener method is called when a character is typed, but is not useful for virtual keys (arrow keys, function keys, etc). Modifier key (shift, control, etc) status (up/down) can be tested with method calls in the listener. These methods are called whenever any key is pressed or released.
Yep, you'll see the arrow keys respond to keyPressed and keyReleased, not keyTyped. My SSCCE:
import java.awt.Dimension;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class ArrowTest extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
public ArrowTest() {
setFocusable(true);
requestFocusInWindow();
addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
myKeyEvt(e, "keyTyped");
}
@Override
public void keyReleased(KeyEvent e) {
myKeyEvt(e, "keyReleased");
}
@Override
public void keyPressed(KeyEvent e) {
myKeyEvt(e, "keyPressed");
}
private void myKeyEvt(KeyEvent e, String text) {
int key = e.getKeyCode();
System.out.println("TEST");
if (key == KeyEvent.VK_KP_LEFT || key == KeyEvent.VK_LEFT)
{
System.out.println(text + " LEFT");
//Call some function
}
else if (key == KeyEvent.VK_KP_RIGHT || key == KeyEvent.VK_RIGHT)
{
System.out.println(text + " RIGHT");
//Call some function
}
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
ArrowTest mainPanel = new ArrowTest();
JFrame frame = new JFrame("ArrowTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
So to solve this, override keyPressed rather than keyTyped if you want to listen to arrow events.
Or for an even better solution: use Key Bindings
Edit
My Key Bindings version:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class ArrowTest extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
public ArrowTest() {
ActionMap actionMap = getActionMap();
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = getInputMap(condition);
for (Direction direction : Direction.values()) {
inputMap.put(direction.getKeyStroke(), direction.getText());
actionMap.put(direction.getText(), new MyArrowBinding(direction.getText()));
}
}
private class MyArrowBinding extends AbstractAction {
public MyArrowBinding(String text) {
super(text);
putValue(ACTION_COMMAND_KEY, text);
}
@Override
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
System.out.println("Key Binding: " + actionCommand);
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
ArrowTest mainPanel = new ArrowTest();
JFrame frame = new JFrame("ArrowTest");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum Direction {
UP("Up", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)),
DOWN("Down", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)),
LEFT("Left", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)),
RIGHT("Right", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
Direction(String text, KeyStroke keyStroke) {
this.text = text;
this.keyStroke = keyStroke;
}
private String text;
private KeyStroke keyStroke;
public String getText() {
return text;
}
public KeyStroke getKeyStroke() {
return keyStroke;
}
@Override
public String toString() {
return text;
}
}
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