Développement GUI avec Swing.
J'ai une boîte de dialogue personnalisée pour choisir un fichier à ouvrir dans mon application; sa classe s'étend javax.swing.JDialog
et contient, entre autres composants, un JFileChooser
, qui peut être basculé pour être affiché ou masqué.
Le composant JFileChooser
gère déjà la touche ESC par lui-même: lorsque le sélecteur de fichiers est affiché (intégré dans ma boîte de dialogue) et que j'appuie sur ÉCHAP, le sélecteur de fichiers se cache.
Maintenant, je voudrais que ma boîte de dialogue fasse de même: lorsque j'appuie sur ÉCHAP, je veux que la boîte de dialogue se ferme. Attention, lorsque le sélecteur de fichier incorporé est affiché, la touche ESC ne doit que le masquer.
Des idées ?
Utilisez InputMap
et ActionMap
pour traiter les actions clés dans Swing. Pour fermer proprement la boîte de dialogue, envoyez-lui un événement de fermeture de fenêtre.
De mon weblog :
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
);
}
Vous pouvez utiliser l'extrait de code suivant. C'est mieux car le rootPane obtiendra les é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);
}
Si vous cherchez une technique utilisant de 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);
J'ai eu des problèmes pour mettre en œuvre les deux meilleures réponses. Voici une version plutôt compacte utilisant AbstractAction
pour implémenter automatiquement la plupart des méthodes de Action
, qui fonctionne dans les 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);
Voici le mien, j'ajoute CtrlW comme fermeture shorcut aswell
Action closeAction = new AbstractAction(){
public void actionPerformed(ActionEvent e){
dispose();
}
};
KeyStroke esc = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0);
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(esc, "closex");
getRootPane().getActionMap().put("closex", closeAction);
KeyStroke ctrlW = KeyStroke.getKeyStroke("control W");
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ctrlW, "close");
getRootPane().getActionMap().put("close", closeAction);