Java: JPanel no detecta enlaces de teclado

Problema

He estado jugando para hacer que las combinaciones de teclas funcionen correctamente en una aplicación que he escrito.

Previamente, he estado usando una variante de lo siguiente; panel.registerKeyboardAction(this, "createNewFood", KeyStroke.getKeyStroke(KeyEvent.VK_I, KeyEvent.CTRL_DOWN_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);

Pero como leí en la documentación que registerKeyboardAction estaba marcado como obsoleto, intenté cambiar al método preferido, que es más o menos así; panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("control I"), new NewFoodAction());

Desafortunadamente esto no parece estar funcionando.

Lo que he intentado

He buscado en la web y he probado un montón de enfoques diferentes sin éxito;

  • En lugar de vincular la clave al panel, intenté adjuntarla al resultado de getRootPane(). No funcionó.
  • He probado todas las diferentes "condiciones"; WHEN_IN_FOCUSED_WINDOW, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, WHEN_FOCUSED, no funcionó.
  • Intenté configurar panel.setFocusable(true); no funcionó
  • Intenté usar panel.requestFocusInWindow() solo para ver si podría funcionar condicionalmente; no funcionó

Si adjunto la combinación de teclas a otro componente, por ejemplo, un JTextField, entonces funciona como se supone que debe hacerlo.

Alguna otra información que podría Se relevante (pero realmente no creo que lo sea);

  • Estoy usando MigLayout para el panel. No creo que esto afecte en nada, pero quién sabe.
  • Tengo otras combinaciones de teclas presentes (es decir, otras pulsaciones de teclas vinculadas a otros componentes)

Aquí hay un código de muestra:

public FoodFrame() {
    super("MealTrack");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setPreferredSize(new Dimension(1400, 600));
    setLocation(300, 100);
    setVisible(true);

    panel = new JPanel(new MigLayout("fill", "[grow][]", "[][][][grow][][]"));
    add(panel);
  panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("control I"), new NewFoodAction());

    pack();
    filter.requestFocusInWindow();
}

private class NewFoodAction extends AbstractAction {

    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("called");
    }

}

}

¿Alguien sabe cuál parece ser el problema?

preguntado el 12 de junio de 12 a las 20:06

"Estoy usando MigLayout para el panel. No creo que esto afecte nada, pero quién sabe". Lo harás si lo cambias por FlowLayout y el problema persiste. Para una mejor ayuda antes, publique un SSCCE. -

2 Respuestas

Lo estas haciendo mal. Necesita usar tanto ActionMap como InputMap. Deberías hacer:

panel.getInputMap(con).put(KeyStroke.getKeyStroke("control I"), "createNewFood");
panel.getActionMap().put("createNewFood", new NewFoodAction());

Respondido el 12 de junio de 12 a las 20:06

¡Obras! Leer el aquítutorial dice "Técnicamente, no necesita usar nombres de acción en los mapas; puede usar cualquier objeto como "clave" en los mapas. Sin embargo, por convención, usa una cadena que nombra una acción". Además, ¿cómo es que puedo usar este formato en otros lugares? getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("control F"), new GrabFocus()); - Poyán

la razón es que alguien debe haber registrado una acción con "KeyStroke.getKeyStroke("cont‌​rol F")" como clave. También puede usar cualquier objeto como clave en los mapas de entrada y acción y no es necesario que sea una cadena, el único requisito es que la clave utilizada debe ser la misma en ambos mapas. - suraj chandran

Según el Documentación de Jcomponent, está asignando las entradas clave, pero la acción que realizan no está realmente asignada al panel. por el codigo... panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("control I"), "newfood!");

... también debe tener ...

panel.getActionMap().put("newfood!", [Some actionListener that does what you need to do]);

No estoy del todo seguro de que eso corrija el problema, pero espero que eso lo solucione. ¡Buena suerte!

Respondido el 12 de junio de 12 a las 20:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.