Como capturar um evento de clique do botão Fechar do JFrame?

86

Eu quero chamar um método confirmExit() quando o botão vermelho fechar da barra de título de um JFrame é clicado.

Como posso capturar esse evento?

Também gostaria de evitar que a janela feche se o usuário optar por não continuar.

alxcyl
fonte

Respostas:

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

Se você também deseja impedir que a janela feche, a menos que o usuário escolha 'Sim', você pode adicionar:

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

Substituir método de fechamento de janela.

public void windowClosing(WindowEvent e)

É invocado quando uma janela está em processo de fechamento. A operação de fechamento pode ser substituída neste ponto.

Shashank Kadne
fonte
3
Isso funcionará se o usuário fechar o aplicativo (por exemplo, pressionando Cmd + Q em um Mac)? A classe que implementa esse método precisa declarar implements WindowListenerpara que esse código funcione? Nesse caso, pode ser bom incluir isso na resposta. Caso contrário, esta é uma solução elegante.
intcreator de
@brandaemon Se você adicionar esta linha de código ao topo de seu método main () "System.setProperty (" apple.eawt.quitStrategy "," CLOSE_ALL_WINDOWS ");" em seguida, ele chamará o windowListener quando Cmd + Q for pressionado no mac.
retrovius
2
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

também funciona. Primeiro crie um JFrame chamado frame e, em seguida, adicione esse código abaixo.

Russell
fonte
9
Mas isso não executa o confirmExit()método como o OP gostaria
dia
Mas faz a mesma coisa
Russell em
11
Não, não quero simplesmente fechar o programa. Eu quero fazer algo antes que aconteça.
alxcyl
oh desculpe, eu não sabia disso.
Russell
1
"O que eu quero fazer é ligar ... confirmExit()quando [o X] for clicado." E o comentário anterior não está relacionado ao OQ.
DSlomer64 de
1

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

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

Phidippus
fonte
1

Isso é o que eu coloquei como uma opção de menu onde fiz um botão em um JFramepara exibir outro JFrame. Queria apenas que a nova moldura ficasse visível e não destruir a que estava por trás dela. Eu inicialmente escondi o primeiro JFrame, enquanto o novo se tornou visível. Ao fechar o novo JFrame, descartei-o seguido por uma ação de tornar o antigo visível novamente.

Observação: o código a seguir expande a resposta de Ravinda e ngé um 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
fonte
-2

Experimente isto:

setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

Vai funcionar.

vikas bodade
fonte