¿Cómo capturar un evento de clic de botón de cierre de JFrame?

86

Quiero llamar a un método confirmExit()cuando se hace clic en el botón rojo de cierre de la barra de título de un JFrame.

¿Cómo puedo capturar ese evento?

También me gustaría evitar que la ventana se cierre si el usuario elige no continuar.

alxcyl
fuente

Respuestas:

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 también desea evitar que la ventana se cierre a menos que el usuario elija 'Sí', puede agregar:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Ravindra Gullapalli
fuente
25

Anular el método de cierre de ventana.

public void windowClosing(WindowEvent e)

Se invoca cuando una ventana está en proceso de cerrarse. La operación de cierre se puede anular en este punto.

Shashank Kadne
fuente
3
¿Funcionará esto si el usuario cierra la aplicación (por ejemplo, presionando Cmd + Q en una Mac)? ¿La clase que implementa este método tiene que declarar implements WindowListenerpara que este código funcione? Si es así, sería bueno incluirlo en la respuesta. De lo contrario, esta es una solución elegante.
intcreator
@brandaemon Si agrega esta línea de código en la parte superior de su método main () "System.setProperty (" apple.eawt.quitStrategy "," CLOSE_ALL_WINDOWS ");" luego llamará al windowListener cuando se presione Cmd + Q en mac.
retrovius
2
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

también funciona. Primero cree un marco llamado JFrame, luego agregue este código debajo.

Russell
fuente
9
Pero esto no ejecuta el confirmExit()método como le gustaría al OP
hage
Sin embargo, hace lo mismo
Russell
11
No, no quiero simplemente cerrar el programa. Quiero hacer algo antes de que suceda.
alxcyl
oh lo siento, no lo sabía.
Russell
1
"Lo que quiero hacer es llamar ... confirmExit()cuando se hace clic en [la X]". Y el comentario anterior no está relacionado con OQ.
DSlomer64
1

Esto puede funcionar:

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

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

Phidipo
fuente
1

Esto es lo que puse como opción de menú donde hice un botón en un JFramepara mostrar otro JFrame. Quería que solo el nuevo marco fuera visible, y no destruir el que estaba detrás. Inicialmente escondí el primero JFrame, mientras que el nuevo se hizo visible. Al cerrar el nuevo JFrame, lo deseché seguido de una acción de hacer que el viejo volviera a ser visible.

Nota: El siguiente código se expande a partir de la respuesta de Ravinda y nges 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
fuente
-2

Prueba esto:

setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

Funcionará.

vikas bodade
fuente