Java KeyListener não registra as teclas de seta

Eu estou escrevendo um programa simples em Java que inclui um KeyListener com o seguinte sobrepondo o método KeyTyped:

@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 } } 

Quando eu digito algo diferente de teclas de seta (por exemplo, “a”), ele imprime TEST como deveria. No entanto, quando eu digito uma tecla de seta numpad, ela imprime somente TEST e, quando digito uma tecla de seta padrão, ela não imprime nada. Isso é possivelmente porque eu estou em um laptop, ou eu cometi um erro bobo em algum lugar?

Sim, você verá as teclas de seta responder a keyPressed e keyReleased, não keyTyped. Meu 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(); } }); } } 

Então, para resolver isso, substitua keyPressed em vez de keyTyped se você quiser ouvir events de seta.

Ou para uma solução ainda melhor: use as chaves

Editar
Versão My Key Bindings:

 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; } }