61 votes

Swing: comment fermer une boîte de dialogue lorsque la touche ESC est enfoncée?

Développement du GUI avec Swing.

J'ai un dialogue personnalisée pour choisir un fichier à ouvrir dans mon application; sa classe étend javax.swing.JDialog et contient, entre autres composants, JFileChooser, qui peut être activée pour être affichée ou masquée.

L' JFileChooser composant déjà gère la touche ESC par elle-même: lorsque le sélecteur de fichier est indiqué (intégré dans ma boîte de dialogue) et j'appuie sur ESC, le sélecteur de fichier se cache.

Maintenant, je voudrais que mon dialogue à faire de même: lorsque j'appuie sur ECHAP, je veux la boîte de dialogue fermer. Rappelez-vous, quand le intégré sélecteur de fichier s'affiche, la touche ESC ne doit cacher.

Des idées ?

71voto

Ayman Points 3980

Vous pouvez utiliser l'extrait suivant. Cela est préférable car rootPane obtiendra des événements de n’importe quel composant de la boîte de dialogue. Vous pouvez remplacer setVisible (false) par dispose () si vous le souhaitez.

 public static void addEscapeListener(final JDialog dialog) {
    ActionListener escListener = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            dialog.setVisible(false);
        }
    };

    dialog.getRootPane().registerKeyboardAction(escListener,
            KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
            JComponent.WHEN_IN_FOCUSED_WINDOW);

}
 

62voto

Tom Hawtin - tackline Points 82671

Utilisez InputMap et ActionMap pour gérer les actions clés dans Swing. Pour fermer la boîte de dialogue proprement, envoyez-lui un événement de fermeture de fenêtre.

De mon blog :

 private static final KeyStroke escapeStroke = 
    KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); 
public static final String dispatchWindowClosingActionMapKey = 
    "com.spodding.tackline.dispatch:WINDOW_CLOSING"; 
public static void installEscapeCloseOperation(final JDialog dialog) { 
    Action dispatchClosing = new AbstractAction() { 
        public void actionPerformed(ActionEvent event) { 
            dialog.dispatchEvent(new WindowEvent( 
                dialog, WindowEvent.WINDOW_CLOSING 
            )); 
        } 
    }; 
    JRootPane root = dialog.getRootPane(); 
    root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( 
        escapeStroke, dispatchWindowClosingActionMapKey 
    ); 
    root.getActionMap().put( dispatchWindowClosingActionMapKey, dispatchClosing 
    ); 
}
 

15voto

Java42 Points 4375

Si vous recherchez une technique utilisant les nouvelles fonctionnalités de Java 8, essayez une expression lambda:

 dialog.getRootPane().registerKeyboardAction(e -> {
    window.dispose();
}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
 

ou

 KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
int w = JComponent.WHEN_IN_FOCUSED_WINDOW;
dialog.getRootPane().registerKeyboardAction(e -> window.dispose(), k, w);
 

4voto

skia.heliou Points 26

J'ai eu des problèmes pour mettre en œuvre les deux réponses principales. Voici une version plutôt compacte utilisant AbstractAction pour implémenter automatiquement la plupart des méthodes de Action , qui fonctionnent dans des champs textuels (selon la demande de @ pratikabu):

 final AbstractAction escapeAction = new AbstractAction() {
    private static final long serialVersionUID = 1L;

    @Override
    public void actionPerformed(ActionEvent ae) {
        dispose();
    }
};

getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
        .put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "ESCAPE_KEY");
getRootPane().getActionMap().put("ESCAPE_KEY", escapeAction);
 

Références

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X