2011-02-02 18 views
5

Tengo una aplicación Swing que necesita mostrar diferentes conjuntos de controles en función de si se presionan las teclas de control o alt. Agregué un KeyListener al componente principal, pero se notifica solo si se selecciona ese componente, no si se selecciona un subcomponente. ¿Hay alguna forma de escuchar eventos para un componente y todos los descendientes?Escucha de eventos clave para una jerarquía de componentes

Editar:

He intentado utilizar InputMap del componente principal, pero ningún caso se dispara cuando se pulsa una tecla de modificación. En concreto, tengo el siguiente código:

InputMap inputMap = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 
inputMap.put(KeyStroke.getKeyStroke("pressed CONTROL"), "test1"); 
inputMap.put(KeyStroke.getKeyStroke("released CONTROL"), "test2"); 
ActionMap actionMap = panel.getActionMap(); 
actionMap.put("test1", new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("pressed"); 
    } 
}); 
actionMap.put("test2", new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("released"); 
    } 
}); 

Al presionar y soltar la tecla de control, esto imprimirá "liberado", pero no "presionado". Nada más está registrando nada en ningún InputMap, por lo que no es como si algo más estuviera registrado para el mismo golpe de tecla.

Respuesta

2

Es posible que desee intentar utilizar el enlace de teclas en lugar de KeyListeners. La vinculación de claves es una construcción de nivel más alto y puede escuchar las pulsaciones de teclas incluso si el componente que "escucha" no tiene el foco, a diferencia de KeyListeners. Puede encontrar más información al respecto en los tutoriales de Swing: How to use key bindings

2

Puede considerar el uso de the InputMap and ActionMap de algunos componentes oscilantes. Puede especificar con JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT para indicar que desea responder a la pulsación de tecla dada cuando el componente o sus subcomponentes están enfocados.

Si no desea utilizar el InputMap o ActionMap, usted podría agregar el KeyListener a todos los componentes hijos:

for (Component child : parent.getComponents()) 
{ 
child.addKeyListener(keyListener); 
} 
+0

Esto funciona para pulsaciones de teclas "CONTROL liberado" pero no para "CONTROL presionado". Del mismo modo para alt y shift. –

+0

@ Adam Crume Bueno, algunos controles pueden estar escuchando ctrl, alt o shift. Sin embargo, al menos probar con otras teclas, inicia la acción dada al presionar la tecla. Es cierto, sin embargo, se lanzará repetidamente mientras se presiona la tecla. –

+0

Lo que Zack menciona con InputMap y ActionMap usa enlaces de teclas. Nuevamente, revise el tutorial que resolverá su problema. –

4

acaba de cambiar su getKeyStroke(...) invocación de este modo:

InputMap inputMap = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, KeyEvent.CTRL_DOWN_MASK, false), "test1"); 
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, 0, true), "test2"); 
ActionMap actionMap = panel.getActionMap(); 
actionMap.put("test1", new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("pressed"); 
    } 
}); 
actionMap.put("test2", new AbstractAction() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     System.out.println("released"); 
    } 
}); 

que me llevó mucho de ensayo y error para llegar con el encantamiento correcto.

Es importante utilizar getInputMap (JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT), para poder escuchar widgets secundarios y más pequeños.

Es especialmente importante especificar KeyEvent.CTRL_DOWN_MASK, además de KeyEvent.VK_CONTROL al buscar la tecla de control PRESIONAR eventos. Este detalle particular faltaba en su ejemplo de código modificado.

+0

Tuve problemas con 'WHEN_ANCESTOR_OF_FOCUSED_COMPONENT' y me pareció más útil usar' WHEN_IN_FOCUSED_WINDOW'. – jan

Cuestiones relacionadas