2012-01-22 2 views
9

Я пишу простую программу в Java, которая включает в себя KeyListener со следующим перекрывая они KeyTyped метод: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, как и следовало ожидать. Однако, когда я набираю клавишу стрелки numpad, она печатает только 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

Редактировать
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; 
    } 
} 
+0

Это интересно. Есть ли причина, по которой они не отвечают на keyPressed? – Landric

+1

@ Landric: извините, но я понятия не имею, и я почесываю голову над этим. Я никогда не сталкивался с этим сам, потому что для чего-то подобного я всегда использовал Key Bindings, и я настоятельно рекомендую вам сделать то же самое. –

+1

@Landric: см. Править для версии ключа [SSCCE] для ключевых слов (http://SSCCE.org). –

Смежные вопросы