KeyListener que no responde para JFrame

Resuelto Tomek asked hace 16 años • 12 respuestas

Estoy intentando implementar un KeyListenerpara mi JFrame. En el constructor, estoy usando este código:

System.out.println("test");
addKeyListener(new KeyListener() {
    public void keyPressed(KeyEvent e) { System.out.println( "tester"); }

    public void keyReleased(KeyEvent e) { System.out.println("2test2"); }

    public void keyTyped(KeyEvent e) { System.out.println("3test3"); }
});

Cuando lo ejecuto, testaparece el mensaje en mi consola. Sin embargo, cuando presiono una tecla, no recibo ninguno de los otros mensajes, como si KeyListenerni siquiera estuviera allí.

Estaba pensando que podría deberse a que el foco no está en el JFrame
y por eso KeyListenerno reciben ningún evento. Pero estoy bastante seguro de que lo es.

¿Hay algo que me falta?

Tomek avatar Nov 13 '08 17:11 Tomek
Aceptado

Si no desea registrar un oyente en cada componente,
puede agregar el suyo propioKeyEventDispatcher a KeyboardFocusManager:

public class MyFrame extends JFrame {    
    private class MyDispatcher implements KeyEventDispatcher {
        @Override
        public boolean dispatchKeyEvent(KeyEvent e) {
            if (e.getID() == KeyEvent.KEY_PRESSED) {
                System.out.println("tester");
            } else if (e.getID() == KeyEvent.KEY_RELEASED) {
                System.out.println("2test2");
            } else if (e.getID() == KeyEvent.KEY_TYPED) {
                System.out.println("3test3");
            }
            return false;
        }
    }
    public MyFrame() {
        add(new JTextField());
        System.out.println("test");
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.addKeyEventDispatcher(new MyDispatcher());
    }

    public static void main(String[] args) {
        MyFrame f = new MyFrame();
        f.pack();
        f.setVisible(true);
    }
}
Peter avatar Sep 04 '2009 14:09 Peter

Debe agregar su keyListener a cada componente que necesite. Sólo el componente con el foco enviará estos eventos. Por ejemplo, si solo tiene un TextBox en su JFrame, ese TextBox tiene el foco. Por lo tanto, también debes agregar un KeyListener a este componente.

El proceso es el mismo:

myComponent.addKeyListener(new KeyListener ...);

Nota: Algunos componentes no se pueden enfocar como JLabel.

Para configurarlos como enfocables necesitas:

myComponent.setFocusable(true);
bruno conde avatar Nov 13 '2008 13:11 bruno conde

InputMaps y ActionMaps fueron diseñados para capturar los eventos clave del componente, él y todos sus subcomponentes, o la ventana completa. Esto se controla mediante el parámetro en JComponent.getInputMap(). Consulte Cómo utilizar combinaciones de teclas para obtener documentación.

La belleza de este diseño es que uno puede elegir qué pulsaciones de teclas son importantes para monitorear y ejecutar diferentes acciones en función de esas pulsaciones de teclas.

Este código llamará a dispose() en un JFrame cuando se presione la tecla de escape en cualquier parte de la ventana. JFrame no deriva de JComponent, por lo que debe usar otro componente en JFrame para crear el enlace de claves. El panel de contenido podría ser uno de esos componentes.

InputMap inputMap; 
ActionMap actionMap;
AbstractAction action;
JComponent component;

inputMap  = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
actionMap = component.getActionMap();

action    = new AbstractAction()
{
   @Override
   public void actionPerformed(ActionEvent e)
   {
      dispose();
   }
};

inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dispose");
actionMap.put("dispose", action);
Nathan avatar Feb 23 '2013 00:02 Nathan