Java: Como cancelar a saída do aplicativo

Em um dos meus programas, desejo que apareça uma caixa de diálogo quando o usuário tentar sair do aplicativo. O usuário deve optar por salvar algum estado do programa, não salvar ou cancelar a operação de saíd

Eu escrevi isso na tentativa de encontrar uma solução primeiro e depois a implementamos:

import javax.swing.*;
import java.awt.Dimension;
import java.awt.event.*;

class WL implements WindowListener
{
    private boolean statussaved;
    private JFrame tframe;

    WL (JFrame frame)
    {
        statussaved = false;
        tframe = frame;
    }

    @Override public void windowActivated (WindowEvent w) { }
    @Override public void windowClosed (WindowEvent w) { }
    @Override public void windowDeactivated (WindowEvent w) { }
    @Override public void windowDeiconified (WindowEvent w) { }
    @Override public void windowIconified (WindowEvent w) { }
    @Override public void windowOpened (WindowEvent w) { }

    @Override public void windowClosing (WindowEvent w)
    {
        if (statussaved)
        {
            return;
        }

        final JDialog diag = new JDialog (tframe, "Save Progress", true);
        diag.setPreferredSize (new Dimension (500, 100));
        diag.setResizable (false);
        diag.setDefaultCloseOperation (JDialog.DISPOSE_ON_CLOSE);

        JPanel notifypanel = new JPanel ();
        notifypanel.add (new JLabel ("Do you want to save the current status ?"));

        JButton yesbutton = new JButton ("Yes");
        JButton nobutton = new JButton ("No");
        JButton cancelbutton = new JButton ("Cancel");

        yesbutton.addActionListener (new ActionListener ()
        {
            @Override public void actionPerformed (ActionEvent a)
            {
                //SAVE THE STATUS

                System.out.println ("Saving status...");
                statussaved = true;

                diag.dispose ();
                tframe.dispose ();
            }
        });

        nobutton.addActionListener (new ActionListener ()
        {
            @Override public void actionPerformed (ActionEvent a)
            {
                //just exit/close the application

                diag.dispose ();
                tframe.dispose ();
            }
        });

        cancelbutton.addActionListener (new ActionListener ()
        {
            @Override public void actionPerformed (ActionEvent a)
            {
                //DON'T EXIT !!!

                diag.dispose ();
            }
        });

        notifypanel.add (yesbutton);
        notifypanel.add (nobutton);
        notifypanel.add (cancelbutton);

        diag.setContentPane (notifypanel);

        diag.pack ();
        diag.setVisible (true);
    }
}

public class SaveTest
{
    public static void main (String[] args)
    {
        SwingUtilities.invokeLater (new Runnable ()
        {
            @Override public void run ()
            {
                JFrame frame = new JFrame ("Save Test");
                frame.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
                frame.addWindowListener (new WL (frame));

                JLabel lab = new JLabel ("just some information");

                frame.setPreferredSize (new Dimension (400, 300));
                frame.setResizable (false);
                frame.add (lab);
                frame.pack ();
                frame.setVisible (true);
            }
        });
    }
}

Compila e executa sem nenhuma alteração, para que você possa testá-l

As opções "Sim" e "Não" funcionam como esperado, mas não faço a menor idéia do que escrever noActionListener do botão "Cancelar". O que eu quero é que, quando o usuário clica no botão "Cancelar", a caixa de diálogo desaparece, mas a janela principal permanece visível (ou seja, o programa continua em execução

Agora, como tudo isso é implementado nowindowClosing, é claro que algum tipo de sinal de descarte foi enviado para destruir oJFrame. Isso significa que provavelmente não há como isso ser feito no design atual. Não me importo de reorganizar / redesenhar tudo isso para fazer funcionar. É só que ... eu não sei como.

Alguma ideia

questionAnswers(4)

yourAnswerToTheQuestion