2012-02-12 6 views
6

Su uno dei miei programmi, voglio una finestra di dialogo venga visualizzato quando l'utente tenta di chiudere l'applicazione. L'utente deve quindi scegliere di salvare alcuni stati del programma, non salvare o annullare l'operazione di uscita.Java: Come cancellare l'uscita dell'applicazione

ho scritto questo nel tentativo di trovare una soluzione prima e girarci intorno poi attuarlo:

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

Si compila e funziona senza alcun cambiamento, in modo da poter testare.

Le scelte "Sì" e "No" funzionano come previsto, ma non ho assolutamente idea di cosa scrivere nello ActionListener del pulsante "Annulla". Quello che voglio è che quando l'utente fa clic sul pulsante "Annulla", la finestra di dialogo scompare, ma la finestra principale rimane visibile (ovvero il programma continua a essere eseguito).

Ora, dal momento che tutto ciò è implementato nel metodo windowClosing, è una specie di chiaro che una sorta di segnale di smaltire fu mandato al fine di distruggere il JFrame. Ciò significa che probabilmente non c'è modo di farlo nel design attuale. Non mi dispiace riorganizzare/ridisegnare tutto questo per farlo funzionare. È solo ... non so come.

Qualche idea?

risposta

9

Sostituire

mainframe.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE); 

con

mainframe.setDefaultCloseOperation (JFrame.DO_NOTHING_ON_CLOSE); 

Se l'utente annulla la chiusura - non fare nulla. Se è d'accordo - chiama il numero dispose() manualmente.

+0

Grazie, l'ho fatto e funziona :). PS: In realtà il cambiamento è per 'mainframe', non' diag'. –

6

Dai un'occhiata alla JOptionPane, che gestisce la maggior parte di questa roba per te, per esempio

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

vostre DefaultCloseOperation deve essere DO_NOTHING_ON_CLOSE in modo che il dialogo in grado di gestire le cose - in caso contrario la finestra otterrà smaltiti prima che l'utente può annullarlo. Quindi chiudi manualmente la finestra o esci dall'applicazione o in base alla scelta dell'utente.

+0

Grazie !!! Tutto quello che dovevo fare è impostare 'DefaultCloseOperation' su' mainframe' su 'DO_NOTHING_ON_CLOSE' e ha funzionato. Di dove sei ? Dovrei mandarti qualche birra :). –

+0

Felice di aiutare. Sono dall'altra parte dell'Europa, in modo forse un po 'lontano per le birre, ma grazie comunque ;-) – DNA

+0

Si prega di [accettare] (http://meta.stackexchange.com/a/65088/155831) la risposta quando hai una possibilità. –