Wie erfasse ich das Klickereignis zum Schließen eines JFrames?

83

Ich möchte eine Methode aufrufen, confirmExit()wenn auf die rote Schaltfläche zum Schließen der Titelleiste eines JFrames geklickt wird.

Wie kann ich dieses Ereignis erfassen?

Ich möchte auch verhindern, dass das Fenster geschlossen wird, wenn der Benutzer nicht fortfährt.

Alxcyl
quelle

Antworten:

143
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);
        }
    }
});

Wenn Sie auch verhindern möchten, dass das Fenster geschlossen wird, es sei denn, der Benutzer wählt "Ja", können Sie Folgendes hinzufügen:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Ravindra Gullapalli
quelle
26

Fenster-Schließmethode überschreiben.

public void windowClosing(WindowEvent e)

Es wird aufgerufen, wenn ein Fenster gerade geschlossen wird. Der Schließvorgang kann an dieser Stelle überschrieben werden.

Shashank Kadne
quelle
3
Funktioniert dies, wenn der Benutzer die Anwendung schließt (z. B. durch Drücken von Cmd + Q auf einem Mac)? Muss die Klasse, die diese Methode implementiert, deklarieren, implements WindowListenerdamit dieser Code funktioniert? Wenn ja, könnte es gut sein, dies in die Antwort aufzunehmen. Ansonsten ist dies eine elegante Lösung.
Intcreator
@brandaemon Wenn Sie diese Codezeile am Anfang Ihrer main () -Methode "System.setProperty (" apple.eawt.quitStrategy "," CLOSE_ALL_WINDOWS ") hinzufügen;" dann ruft es den windowListener auf, wenn Cmd + Q auf dem Mac gedrückt wird.
Retrovius
4
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

funktioniert auch. Erstellen Sie zuerst einen JFrame mit dem Namen frame und fügen Sie dann diesen Code darunter hinzu.

Russell
quelle
8
Aber dies führt die confirmExit()Methode nicht so aus, wie es das OP möchte
hage
Es macht das gleiche
Russell
11
Nein, ich möchte das Programm nicht einfach schließen. Ich möchte etwas tun, bevor es passiert.
Alxcyl
Oh, tut mir leid, das wusste ich nicht.
Russell
1
"Ich möchte anrufen ... confirmExit()wenn [das X] angeklickt wird." Und der vorherige Kommentar hat nichts mit OQ zu tun.
DSlomer64
1

Dies kann funktionieren:

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");
    }
});

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

Phidippus
quelle
1

Dies ist, was ich als Menüoption gesetzt habe, wo ich eine Schaltfläche auf a gemacht habe JFrame, um eine andere anzuzeigen JFrame. Ich wollte, dass nur der neue Rahmen sichtbar ist und nicht der dahinter liegende. Ich habe zuerst den ersten versteckt JFrame, während der neue sichtbar wurde. Nach dem Schließen des neuen habe JFrameich es entsorgt, gefolgt von einer Aktion, das alte wieder sichtbar zu machen.

Hinweis: Der folgende Code erweitert Ravindas Antwort und ngist ein 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
quelle
-2

Versuche dies:

setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

Es wird klappen.

Vikas Bodade
quelle