Capturar teclas en Swing/ Keys Capture in Swing

Para capturar las combinaciones de teclas dentro de una aplicación swing,  se deben de utilizar dos  objetos (ActionMap e  InputMap ).

1. Creamos nuestro Mapa de accion.

ActionMap mapaAccion = jPanel1.getActionMap();

2. Indicamos el componente donde queremos que trabaje el mapa.

InputMap map = jPanel1.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

3. Seleccionamos la combinación de teclas.

//F1
KeyStroke key_F1 = KeyStroke.getKeyStroke(KeyEvent.VK_F1,0);

// CTRL + O
KeyStroke ctrl_O = KeyStroke.getKeyStroke(KeyEvent.VK_O,Event.CTRL_MASK);

// CTRL + C, CTRL + V
KeyStroke ctrl_C = KeyStroke.getKeyStroke(KeyEvent.VK_C,Event.CTRL_MASK, true);
KeyStroke ctrl_V = KeyStroke.getKeyStroke(KeyEvent.VK_V,Event.CTRL_MASK, true);


4. Indicamos y agregamos la acción a ejecutar.

//Key Actions
map.put(key_F1, «accion_F1»);
mapaAccion.put(«accion_F1»,Accion_F1());


public AbstractAction Accion_F1(){
return new AbstractAction() { public void actionPerformed(ActionEvent e) { imprimir(«F1»); } };
}

public void imprimir(String cadena){
System.out.println(«Accion :»+ cadena);
jTextField1.setText(cadena);
}

Aqui el ejemplo:

// ACCIONES
public void mapeoTeclas(){

ActionMap mapaAccion = jPanel1.getActionMap();
InputMap map = jPanel1.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

//F1
KeyStroke key_F1 = KeyStroke.getKeyStroke(KeyEvent.VK_F1,0);

// CTRL + O
KeyStroke ctrl_O = KeyStroke.getKeyStroke(KeyEvent.VK_O,Event.CTRL_MASK);

// CTRL + C, CTRL + V
KeyStroke ctrl_C = KeyStroke.getKeyStroke(KeyEvent.VK_C,Event.CTRL_MASK, true);
KeyStroke ctrl_V = KeyStroke.getKeyStroke(KeyEvent.VK_V,Event.CTRL_MASK, true);

//Key Actions
map.put(key_F1, «accion_F1»);
mapaAccion.put(«accion_F1»,Accion_F1());

map.put(ctrl_O , «accion_ctrl_o»);
mapaAccion.put(«accion_ctrl_o»,Accion_CTRLO());

map.put(ctrl_C , «accion_ctrl_C»);
mapaAccion.put(«accion_ctrl_C»,Accion_CTRLC());

map.put(ctrl_V , «accion_ctrl_V»);
mapaAccion.put(«accion_ctrl_V»,Accion_CTRLV());
}

public AbstractAction Accion_CTRLO(){
return new AbstractAction() { public void actionPerformed(ActionEvent e) { imprimir(«CTRL + O»); } };
}

public AbstractAction Accion_CTRLC(){
return new AbstractAction() { public void actionPerformed(ActionEvent e) { imprimir(«CTRL + C»); } };
}

public AbstractAction Accion_CTRLV(){
return new AbstractAction() { public void actionPerformed(ActionEvent e) { imprimir(«CTRL + V»); } };
}

public AbstractAction Accion_F1(){
return new AbstractAction() { public void actionPerformed(ActionEvent e) { imprimir(«F1»); } };
}

public void imprimir(String cadena){
System.out.println(«Accion :»+ cadena);
jTextField1.setText(cadena);
}

Solo hay que ejecutar el metodo mapeoTeclas() en el constructor de la clase.

Agrego el codigo fuente:

Source

Source

Saludos

8 comentarios en “Capturar teclas en Swing/ Keys Capture in Swing

  1. lechon dijo:

    Hola,
    he estado revisando este interesante artículo sobre la captura de teclado y me gustaría que me resolvieras una duda.
    ¿¿La captura de teclado que has explicado esta centrada en una clase de la aplicación o funcionara para todos los elementos que compongan la aplicación??
    Lo pregunto por que estoy buscando un modo de poder capturar os eventos de teclado dentro de la aplicación independientemente del objeto que tenga el foco en ese momento.
    Gracias Lechon.

    • jaehoo dijo:

      Hola, si el código es para un solo componente (JPanel) aunque puede ser cualquiera… JFrame, JButton, etc…

      Para este ejemplo yo lo coloque en el Panel ya que todos los componentes están dentro él, así no importa que componente tenga el foco, mientras este en el panel las combinaciones van a funcionar.

      Para tu idea creo que podrias definir las combinaciones de forma estatica en una clase a parte y despúes invocarlas en cada una de las ventanas de tu app… así todas compartirían las mismas..

      Saludos

      • lechon dijo:

        Después de revisar tu código se me había ocurrido que la idea podría ser algo parecido a lo que has comentado.
        La estructura de mi aplicación esta formada por un JFrame con un JtabbedPane y dentro de este los paneles con la información que tengo que mostrar.
        En ese caso debería crear la clase para el JFrame o también para cada uno de los JPanels para que me capture los eventos aunque no tenga el foco.

        Un saludo, Lechon.

      • jaehoo dijo:

        Si tu JtabbedPane estan dentro del JFrame principal solo basta con que se lo asocies a ese frame, y en teoria los componentes dentro de él deberían funcionar con la combinacion siempre y cuando el foco este en ese frame.

        JFrame <———– se lo incluyes aqui
        – JtabbedPane

        Y si no pues puedes probar metiendo un panel en el Frame que es lo más común, y adentro del panel tus pestañas:

        JFrame
        -JPanel <———– se lo incluyes aquí
        – JtabbedPane

  2. lechon dijo:

    He estado realizando unas pruebas con tu código y para los paneles me va perfectamente, compartiendo el «InputMap» y el «ActionMap» entre los diferentes paneles consigo que me capture los eventos y ejecute el método del println.
    Lo único es que no he encontrado en el JFrame ningún método para poder obtener el InputMap y ActionMap de este componente para aplicárselo directamente al Frame.

Deja un comentario

Este sitio utiliza Akismet para reducir el spam. Conoce cómo se procesan los datos de tus comentarios.