Java KeyListener未注册箭头键

我正在用Java编写一个简单的程序,其中包含一个KeyListener,其中包含以下覆盖它们的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 } } 

当我键入除箭头键以外的任何内容(例如“a”)时,它会按原样打印TEST 。 但是,当我键入一个小键盘箭头键时,它只打印TEST ,当我键入标准箭头键时,它根本不打印任何内容。 这可能是因为我在笔记本电脑上,或者我只是在某个地方犯了一个愚蠢的错误?

是的,你会看到箭头键响应keyPressed和keyReleased,而不是keyTyped。 我的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(); } }); } } 

因此,要解决这个问题,如果要监听箭头事件,请覆盖keyPressed而不是keyTyped。

或者为了更好的解决方案:使用Key Bindings

编辑
我的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; } }