Comment capturer un événement de clic sur le bouton de fermeture d'un JFrame?

86

Je souhaite appeler une méthode confirmExit()lorsque l'utilisateur clique sur le bouton de fermeture rouge de la barre de titre d'un JFrame.

Comment puis-je capturer cet événement?

Je voudrais également empêcher la fenêtre de se fermer si l'utilisateur choisit de ne pas continuer.

alxcyl
la source

Réponses:

147
import javax.swing.JOptionPane;
import javax.swing.JFrame;

/*Some piece of code*/
frame.addWindowListener(new java.awt.event.WindowAdapter() {
    @Override
    public void windowClosing(java.awt.event.WindowEvent windowEvent) {
        if (JOptionPane.showConfirmDialog(frame, 
            "Are you sure you want to close this window?", "Close Window?", 
            JOptionPane.YES_NO_OPTION,
            JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION){
            System.exit(0);
        }
    }
});

Si vous souhaitez également empêcher la fermeture de la fenêtre à moins que l'utilisateur ne choisisse «Oui», vous pouvez ajouter:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Ravindra Gullapalli
la source
25

Override windowClosing Méthode.

public void windowClosing(WindowEvent e)

Il est appelé lorsqu'une fenêtre est en cours de fermeture. L'opération de fermeture peut être annulée à ce stade.

Shashank Kadne
la source
3
Cela fonctionnera-t-il si l'utilisateur ferme l'application (par exemple, en appuyant sur Cmd + Q sur un Mac)? La classe qui implémente cette méthode doit-elle déclarer implements WindowListenerpour que ce code fonctionne? Si tel est le cas, il serait peut-être bon d'inclure cela dans la réponse. Sinon, c'est une solution élégante.
intcreator
@brandaemon Si vous ajoutez cette ligne de code en haut de votre méthode main () "System.setProperty (" apple.eawt.quitStrategy "," CLOSE_ALL_WINDOWS ");" puis il appellera le windowListener lorsque Cmd + Q est pressé sur mac.
retrovius
2
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

fonctionne également. Créez d'abord un JFrame appelé frame, puis ajoutez ce code en dessous.

Russell
la source
9
Mais cela n'exécute pas la confirmExit()méthode comme le souhaite l'OP
hage
Il fait la même chose cependant
Russell
11
Non, je ne veux pas simplement fermer le programme. Je veux faire quelque chose avant que ça n'arrive.
alxcyl
oh désolé, je ne le savais pas.
Russell
1
"Ce que je veux faire, c'est appeler ... confirmExit()quand [le X] est cliqué." Et le commentaire précédent n'a aucun rapport avec OQ.
DSlomer64
1

Cela peut fonctionner:

jdialog.addWindowListener(new WindowAdapter() {
    public void windowClosed(WindowEvent e) {
        System.out.println("jdialog window closed event received");
    }

    public void windowClosing(WindowEvent e) {
        System.out.println("jdialog window closing event received");
    }
});

Source: https://alvinalexander.com/java/jdialog-close-closing-event

Phidippus
la source
1

C'est ce que j'ai mis comme option de menu où j'ai fait un bouton sur un JFramepour en afficher un autre JFrame. Je voulais que seul le nouveau cadre soit visible, et non pas détruire celui qui se trouve derrière. J'ai d'abord caché le premier JFrame, tandis que le nouveau est devenu visible. A la fermeture du neuf JFrame, je m'en suis débarrassé suivi d'une action de rendre l'ancien à nouveau visible.

Remarque: Le code suivant développe la réponse de Ravinda et ngest un JButton:

ng.addActionListener((ActionEvent e) -> {
    setVisible(false);
    JFrame j = new JFrame("NAME");
    j.setVisible(true);
    j.addWindowListener(new java.awt.event.WindowAdapter() {
        @Override
        public void windowClosing(java.awt.event.WindowEvent windowEvent) {
            setVisible(true);
        }
    });
});
Cody
la source
-2

Essaye ça:

setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

Ça va marcher.

vikas bodade
la source