Java KeyListener 未注册箭头键

Posted

技术标签:

【中文标题】Java KeyListener 未注册箭头键【英文标题】:Java KeyListener Not Registering Arrow Keys 【发布时间】:2012-02-16 05:31:32 【问题描述】:

我正在用 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代替keyTyped吗? 【参考方案1】:

是的,您会看到箭头键响应 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

编辑 我的键绑定版本:

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;
   

【讨论】:

@Landric:对不起,但我不知道,对此我摸不着头脑。我自己从来没有遇到过这种情况,因为对于这样的事情,我总是使用键绑定,我强烈建议你也这样做。 @Landric:请参阅我的SSCCE 的键绑定版本的编辑。 +1 用于键绑定版本(如果没有 keyListener sn-p 会更热情:-) @Landric 永远不要使用 keyListeners @Landric - 解释为什么一天两次左右有点无聊...请花点时间搜索这个网站:-)

以上是关于Java KeyListener 未注册箭头键的主要内容,如果未能解决你的问题,请参考以下文章

如何使 KeyListener 起作用?

KeyListener 多久检查一次键盘输入? (Java 图形用户界面)

Keylistener 不适用于 JPanel

java keylistener 未调用

KeyListener 出现问题 [重复]

Java KeyListener 与键绑定