2012-01-22 25 views
9

Estoy escribiendo un sencillo programa en Java que incluye un KeyListener con la siguiente primordial que keyTyped método:Java KeyListener no registrar las teclas de flecha

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

Cuando escribo aparte de las teclas de flecha nada (por ejemplo, "una "), imprime TEST como debería. Sin embargo, cuando introduzco una arrowkey teclado numérico, sólo se imprime TEST y cuando introduzco una flecha clave estándar no se imprime nada en absoluto. ¿Esto es posible porque estoy en una computadora portátil o acabo de cometer un error en alguna parte?

+0

¿Ha intentado utilizar 'keyPressed' en lugar de' keyTyped'? –

Respuesta

20

Sí, verá las teclas de flecha responden a keyPressed y keyReleased, no keyTyped. Mi 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(); 
     } 
     }); 
    } 
} 

Así que para solucionar este problema, en lugar de anulación keyPressed keyTyped si desea escuchar flecha eventos.

O para una solución aún mejor: utilizar Key Bindings

Editar
Mi Key Bindings versión:

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

Eso es interesante. ¿Hay alguna razón por la que no responden a keyPressed? – Landric

+1

@Landric: lo siento, pero no tengo ni idea y me estoy rascando la cabeza por esto. Nunca me he encontrado con esto, porque para algo como esto, siempre uso Key Bindings, y sugiero que hagas lo mismo. –

+1

@Landric: por favor, consulte Edición de una versión Atajos de teclado de mi [SSCCE] (http://SSCCE.org). –

Cuestiones relacionadas