2009-01-13 6 views
12

Estoy escribiendo una aplicación Java Swing usando el aspecto y tacto de metal. Cada vez que hay un JButton en mi aplicación, el usuario usa la tecla Tab para mover el foco al botón y luego pulsa la tecla Intro. ¡No pasa nada! Si presiona la tecla Espacio, los eventos del botón se disparan. ¿Cómo asigno la tecla Enter para activar los mismos eventos que la tecla Espacio? Gracias por tu ayuda.¿Cómo asigno Enter como la clave de activación de todos los JButton en mi aplicación Java?

Respuesta

16

me encontré con lo siguiente:

http://tips4java.wordpress.com/2008/10/25/enter-key-and-button/

Cuando Rob Camick escribe que cuando se utiliza JDK5 y luego sólo tiene que añadir ...

UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE); 

... a la aplicación para resolver el problema. ¡Esto hizo el truco para mí! Y no puedo imaginar nada más simple. Sin embargo, al usar versiones anteriores de Java, tendrá que hacer algo como Richard y Peter describen en sus respuestas a esta pregunta.

+0

Aah, muy agradable ;-) Buen artículo también. Miré la clase MetalLookAndFeel mientras trabajaba en mi respuesta, y esto es solo unas líneas arriba de "Button.focusInputMap" que utilicé. –

0

Lo hace asignando un mapa de entrada/acción para la tecla Intro. Algo como lo siguiente:

// save the command mapping for space 
Object spaceMap = button.getInputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true)); 
// add a mapping from enter to the same command. 
button.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true),spaceMap); 
+0

que no quiero hacer esto para todos los botones en mi solicitud, demasiados problemas. –

+0

Puede subclase JButton y agregar esto en el constructor. –

0

También puede establecer el "botón predeterminado" al botón recientemente enfocado.

Lo hice en una aplicación, y todos los métodos para hacerlo son una pesadilla para mantener y depurar. El hecho es que esto claramente no es lo que los diseñadores de Swing pretendían que sucediera.

+0

Estoy de acuerdo, esto sería una pesadilla. –

4

Aquí hay un ejemplo completo. Richard estaba cerca, pero también necesita asignar ENTER presionado a la acción, no solo liberado. Para que funcione para TODOS los botones, he puesto esta asignación en el mapa de entrada predeterminado para los botones. Añada importaciones, y debería ser ejecutable.


public class Main implements Runnable { 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Main()); 
    } 

    @Override 
    public void run() { 
     setupEnterActionForAllButtons(); 

     JFrame frame = new JFrame("Button test"); 
     frame.getContentPane().add(createButton(), BorderLayout.NORTH); 
     frame.getContentPane().add(createButton(), BorderLayout.SOUTH); 
     frame.pack(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     frame.setVisible(true); 
    } 

    private void setupEnterActionForAllButtons() { 
     InputMap im = (InputMap) UIManager.getDefaults().get("Button.focusInputMap"); 
     Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE")); 
     Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE")); 

     im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction); 
     im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction); 
    } 

    private JButton createButton() { 
     JButton b = new JButton("press enter"); 
     b.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("Pressed"); 
      } 
     }); 

     return b; 
    } 
} 
+0

Muchas gracias Peter. Creo que las mejores respuestas son respuestas basadas en código. ¡Pulgares hacia arriba! –

1

En realidad, este es un problema de apariencia. Está (y debería ser) hasta la apariencia de qué tecla desencadena el botón enfocado.

El "botón predeterminado" funciona porque el L & F que está utilizando utiliza la tecla Intro para el botón predeterminado.

La solución alternativa de Peter cambia explícitamente la tecla de "acción de enfoque" L & F predeterminada, lo que es algo más convincente si me preguntan.

Yo agregaría que no creo que muchos usuarios quieran presionar el botón y luego presionar enter (la mayoría ni siquiera notará el indicador de enfoque) - quieren que la acción predeterminada sea la "correcta" y trabaja donde sea que presionen enter. Esto solo se puede hacer con mapas de entrada como sugiere Richard.

Sin duda, le sugiero obtener una imagen muy clara de lo que sus usuarios realmente quieren y esperan (preferiblemente con referencia a otras aplicaciones que utilizan) antes de cambiar algo a nivel mundial.

0

Extensión a las respuestas anteriores para hacer lo mismo con la radio, casillas de verificación. llamó a este antes de crear componentes

void setupEnterAction(String componentName){ 
    String keyName = componentName + ".focusInputMap"; 
    InputMap im = (InputMap) UIManager.getDefaults().get(keyName); 
    Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE")); 
    Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE")); 
    im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction); 
    im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction); 
} 

public void setEnterEvent(){ 
    setupEnterAction("Button"); 
    setupEnterAction("RadioButton"); 
    setupEnterAction("CheckBox"); 
} 
Cuestiones relacionadas