2012-01-22 15 views
9

我用Java编写一个简单的方案,其中包括以下重写他们的方法的keyTyped一个KeyListener的:的Java的KeyListener不登记箭头键

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

当我输入以外的任何箭头键的其它(如“一“),它应该打印TEST。但是,当我键入一个数字键箭头键时,它只打印TEST,当我键入一个标准箭头键时,它根本不打印任何东西。这可能是因为我在笔记本电脑上,或者我在某个地方犯了一个愚蠢的错误?

+0

您是否尝试过使用'keyPressed',而不是'keyTyped'? –

回答

20

是的,你会看到箭头键响应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; 
    } 
} 
+0

这很有趣。他们有什么理由不回应keyPressed? – Landric

+1

@Landric:对不起,但我不知道,我正在为此挠头。我从来没有遇到过这种情况,因为对于这样的事情,我总是使用Key绑定,而且我强烈建议你也这样做。 –

+1

@Landric:请参阅编辑我的[SSCCE](http://SSCCE.org)的关键绑定版本。 –