Jak uchwycić zdarzenie kliknięcia przycisku zamknięcia JFrame?

86

Chcę wywołać metodę, confirmExit()gdy zostanie kliknięty czerwony przycisk zamykania paska tytułu JFrame.

Jak mogę uchwycić to wydarzenie?

Chciałbym również zapobiec zamykaniu okna, jeśli użytkownik zdecyduje się nie kontynuować.

alxcyl
źródło

Odpowiedzi:

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

Jeśli chcesz również zapobiec zamykaniu okna, chyba że użytkownik wybierze opcję „Tak”, możesz dodać:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Ravindra Gullapalli
źródło
25

Zastąp okno Metoda zamykania.

public void windowClosing(WindowEvent e)

Jest wywoływana, gdy okno jest w trakcie zamykania. W tym momencie można nadpisać operację zamknięcia.

Shashank Kadne
źródło
3
Czy to zadziała, jeśli użytkownik zamknie aplikację (na przykład naciskając Cmd + Q na komputerze Mac)? Czy klasa implementująca tę metodę musi zadeklarować, implements WindowListeneraby ten kod działał? Jeśli tak, dobrze byłoby uwzględnić to w odpowiedzi. W przeciwnym razie jest to eleganckie rozwiązanie.
intcreator
@brandaemon Jeśli dodasz tę linię kodu na początku swojej metody main () "System.setProperty (" apple.eawt.quitStrategy "," CLOSE_ALL_WINDOWS ");" wtedy wywoła windowListener po naciśnięciu Cmd + Q na komputerze Mac.
retrovius
2
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

też działa. Najpierw utwórz JFrame o nazwie frame, a następnie dodaj ten kod pod spodem.

Russell
źródło
9
Ale to nie powoduje wykonania confirmExit()metody tak, jak chciałby tego
operator
Ale robi to samo
Russell
11
Nie, nie chcę po prostu zamknąć programu. Chcę coś zrobić, zanim to się stanie.
alxcyl
przepraszam, nie wiedziałem tego.
Russell
1
„Chcę zadzwonić ... confirmExit()po kliknięciu [X]”. A poprzedni komentarz nie ma związku z OQ.
DSlomer64
1

To może zadziałać:

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

Źródło: https://alvinalexander.com/java/jdialog-close-closing-event

Phidippus
źródło
1

To jest to, co umieściłem jako opcję menu, gdzie zrobiłem przycisk na a, JFrameaby wyświetlić inny JFrame. Chciałem, żeby tylko nowa rama była widoczna, a nie zniszczona za nią. Pierwszą z nich początkowo ukryłem JFrame, a nowa stała się widoczna. Po zamknięciu nowego JFrame, pozbyłem się go, a następnie uczyniłem ponownie widocznym stary.

Uwaga: Poniższy kod rozwija się poza odpowiedzią Ravindy i ngjest 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
źródło
-2

Spróbuj tego:

setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

To będzie działać.

vikas bodade
źródło