2012-02-12 21 views
6

En uno de mis programas, quiero que aparezca un cuadro de diálogo cuando el usuario intente salir de la aplicación. El usuario debe elegir guardar algún estado del programa, no guardar o cancelar la operación de salida.Java: cómo cancelar la salida de la aplicación

escribí esto en un intento de encontrar una solución inmejorable primero y luego ponerlo en práctica:

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

Se compila y se ejecuta sin ningún cambio, por lo que puede probarlo.

Las opciones "Sí" y "No" funcionan como se esperaba, pero no tengo ni idea de qué escribir en el ActionListener del botón "Cancelar". Lo que quiero es que, cuando el usuario haga clic en el botón "Cancelar", el cuadro de diálogo desaparezca, pero la ventana principal permanezca visible (es decir, el programa siga funcionando).

Ahora, dado que todo esto se implementa en el método windowClosing, es claro que se envió algún tipo de señal de eliminación para destruir el JFrame. Esto significa que probablemente no haya forma de hacerlo en el diseño actual. No me importa reorganizar/rediseñar todo esto para que funcione. Es solo ... No sé cómo.

¿Alguna idea?

Respuesta

9

Reemplazar

mainframe.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE); 

con

mainframe.setDefaultCloseOperation (JFrame.DO_NOTHING_ON_CLOSE); 

Si el usuario cancela el cierre - no hacer nada. Si está de acuerdo, llame al dispose() manualmente.

+0

Gracias, lo hice y funciona :). PD: En realidad, el cambio es para 'mainframe', no' diag'. –

6

Eche un vistazo a JOptionPane, que maneja la mayoría de estas cosas para usted, p.

JOptionPane.showConfirmDialog(frame, "please choose one", 
     "information",  
     OptionPane.YES_NO_CANCEL_OPTION, 
     JOptionPane.INFORMATION_MESSAGE); 

Sus DefaultCloseOperation necesidades sean DO_NOTHING_ON_CLOSE para que su diálogo puede manejar las cosas - de lo contrario conseguirá dispuesto la ventana antes de que el usuario puede cancelarla. A continuación, cierra manualmente la ventana o sale de la aplicación o lo que sea según la elección del usuario.

+0

Gracias !!! Todo lo que tuve que hacer es establecer el 'DefaultCloseOperation' en' mainframe' en 'DO_NOTHING_ON_CLOSE' y funcionó. De donde eres ? Debería enviarte algunas cervezas :) –

+0

Me alegra ayudar. Estoy en el otro lado de Europa, así que tal vez un poco lejos para las cervezas, pero gracias de todos modos ;-) – DNA

+0

Por favor [acepte] (http://meta.stackexchange.com/a/65088/155831) la respuesta cuando tienes la oportunidad –

Cuestiones relacionadas