Domanda

Qual è il modo corretto di chiudere un JFrame , come se l'utente avesse premuto il pulsante di chiusura X o premuto Alt + F4 (su Windows)?

L'operazione di chiusura predefinita è impostata nel modo desiderato tramite:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Fa esattamente quello che voglio con i controlli di cui sopra. Questa domanda non riguarda questo.

Quello che voglio davvero fare è far sì che la GUI si comporti come una pressione del pulsante di chiusura X causerebbe il suo comportamento.

Supponiamo che dovessi estendere WindowAdaptor e quindi aggiungere un'istanza del mio adattatore come listener tramite addWindowListener () . Mi piacerebbe vedere la stessa sequenza di chiamate tramite windowDeactivated () , windowClosing () e windowClosed () come accadrebbe con < codice> X pulsante Chiudi. Non tanto strappare la finestra quanto dirgli di strapparsi, per così dire.

È stato utile?

Soluzione

Se si desidera che la GUI si comporti come se si fa clic sul pulsante di chiusura X , è necessario inviare un evento di chiusura della finestra in Window . Il ExitAction da Chiusura di un'applicazione ti consente di aggiungere questa funzionalità a una voce di menu oa qualsiasi componente che utilizza Azione s facilmente.

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

Altri suggerimenti

setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

Non troppo complicato.

Se per Alt-F4 o X intendi " Esci dall'applicazione immediatamente, indipendentemente da quali altre finestre o thread sono in esecuzione " ;, quindi System.exit (...) farà esattamente ciò che vuoi in modo molto brusco, con forza bruta e forse problematico.

Se per Alt-F4 o X intendi nascondere la finestra, allora frame.setVisible (false) è il modo in cui " chiudi " la finestra. La finestra continuerà a consumare risorse / memoria ma può essere resa nuovamente visibile molto rapidamente.

Se per Alt-F4 o X intendi nascondere la finestra e smaltire tutte le risorse che sta consumando, allora frame.dispose () è il modo in cui " chiudi " la finestra. Se il frame era l'ultima finestra visibile e non ci sono altri thread non daemon in esecuzione, il programma verrà chiuso. Se si visualizza di nuovo la finestra, sarà necessario reinizializzare nuovamente tutte le risorse native (buffer grafico, handle di finestra, ecc.)

dispose () potrebbe essere il più vicino al comportamento che desideri davvero. Se la tua app ha più finestre aperte, vuoi Alt-F4 o X per uscire dall'app o semplicemente chiudere la finestra attiva?

Il Java Swing Tutorial on Window Listers potrebbe aiutare a chiarire le cose per te.

Se lo hai fatto per assicurarti che l'utente non possa chiudere la finestra:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

Quindi dovresti cambiare il tuo metodo pullThePlug () in

public void pullThePlug() {
    // this will make sure WindowListener.windowClosing() et al. will be called.
    WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);

    // this will hide and dispose the frame, so that the application quits by
    // itself if there is nothing else around. 
    setVisible(false);
    dispose();
    // if you have other similar frames around, you should dispose them, too.

    // finally, call this to really exit. 
    // i/o libraries such as WiiRemoteJ need this. 
    // also, this is what swing does for JFrame.EXIT_ON_CLOSE
    System.exit(0); 
}

Ho trovato questo l'unico modo che funziona bene con WindowListener e JFrame.DO_NOTHING_ON_CLOSE .

Ecco le tue opzioni:

System.exit(0); // stop program
frame.dispose(); // close window
frame.setVisible(false); // hide window

Uscire dal processo di esecuzione di Java è molto semplice, in pratica è necessario fare solo due cose semplici:

  1. Chiama il metodo java System.exit (...) al punto di chiusura dell'applicazione. Ad esempio, se l'applicazione è basata su frame, è possibile aggiungere listener WindowAdapter e chiamare System.exit (...) all'interno del suo metodo windowClosing (WindowEvent e ) .

Nota: devi chiamare System.exit (...) altrimenti il ??tuo programma è coinvolto in errore.

  1. Evitare eccezioni java impreviste per assicurarsi che il metodo di uscita possa essere chiamato sempre. Se aggiungi System.exit (...) al punto giusto, ma ciò non significa che il metodo può essere chiamato sempre, poiché eccezioni java impreviste potrebbero impedire la chiamata del metodo.

Questo è fortemente correlato alle tue capacità di programmazione.

** Di seguito è riportato un esempio più semplice (basato su JFrame ) che mostra come chiamare il metodo di uscita

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

public class ExitApp extends JFrame
{
   public ExitApp()
   {
      addWindowListener(new WindowAdapter()
      {
         public void windowClosing(WindowEvent e)
         {
           dispose();
           System.exit(0); //calling the method is a must
         }
      });
   }

   public static void main(String[] args)
   {
      ExitApp app=new ExitApp();
      app.setBounds(133,100,532,400);
      app.setVisible(true);
   }
}

Non solo per chiudere JFrame ma anche per attivare eventi WindowListener, prova questo:

myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
  

setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE);

Non solo chiude JFrame ma arresta l'intera applicazione, quindi " EXIT ON CLOSE "

Per ottenere lo stesso risultato devi uscire efficacemente dall'applicazione, semplicemente chiamando

 System.exit(0);

L'effetto è esattamente lo stesso.

Il modo migliore per chiudere a livello di codice un frame Swing è farlo funzionare come farebbe quando la "X" si preme il pulsante. Per fare ciò dovrai implementare WindowAdapter adatto alle tue esigenze e impostare l'operazione di chiusura predefinita del frame per non fare nulla (DO_NOTHING_ON_CLOSE).

Inizializza la cornice in questo modo:

private WindowAdapter windowAdapter = null;

private void initFrame() {

    this.windowAdapter = new WindowAdapter() {
        // WINDOW_CLOSING event handler
        @Override
        public void windowClosing(WindowEvent e) {
            super.windowClosing(e);
            // You can still stop closing if you want to
            int res = JOptionPane.showConfirmDialog(ClosableFrame.this, "Are you sure you want to close?", "Close?", JOptionPane.YES_NO_OPTION);
            if ( res == 0 ) {
                // dispose method issues the WINDOW_CLOSED event
                ClosableFrame.this.dispose();
            }
        }

        // WINDOW_CLOSED event handler
        @Override
        public void windowClosed(WindowEvent e) {
            super.windowClosed(e);
            // Close application if you want to with System.exit(0)
            // but don't forget to dispose of all resources 
            // like child frames, threads, ...
            // System.exit(0);
        }
    };

    // when you press "X" the WINDOW_CLOSING event is called but that is it
    // nothing else happens
    this.setDefaultCloseOperation(ClosableFrame.DO_NOTHING_ON_CLOSE);
    // don't forget this
    this.addWindowListener(this.windowAdapter);
}

Puoi chiudere il frame a livello di codice inviandolo l'evento WINDOW_CLOSING, in questo modo:

WindowEvent closingEvent = new WindowEvent(targetFrame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closingEvent);

Questo chiuderà il frame come il " X " è stato premuto il pulsante.

Se davvero non vuoi che la tua applicazione venga chiusa quando un JFrame viene chiuso,

use: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

invece di: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Ecco una sintesi di come appare la soluzione,

 myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));

Questo esempio mostra come realizzare l'operazione di chiusura della finestra confermata.

La finestra ha un adattatore per finestra che imposta l'operazione di chiusura predefinita su EXIT_ON_CLOSE o DO_NOTHING_ON_CLOSE in base alla risposta in OptionDialog .

Il metodo closeWindow di ConfirmedCloseWindow genera un evento di chiusura della finestra e può essere utilizzato ovunque, ad es. come azione di una voce di menu

public class WindowConfirmedCloseAdapter extends WindowAdapter {

    public void windowClosing(WindowEvent e) {

        Object options[] = {"Yes", "No"};

        int close = JOptionPane.showOptionDialog(e.getComponent(),
                "Really want to close this application?\n", "Attention",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.INFORMATION_MESSAGE,
                null,
                options,
                null);

        if(close == JOptionPane.YES_OPTION) {
           ((JFrame)e.getSource()).setDefaultCloseOperation(
                   JFrame.EXIT_ON_CLOSE);
        } else {
           ((JFrame)e.getSource()).setDefaultCloseOperation(
                   JFrame.DO_NOTHING_ON_CLOSE);
        }
    }
}

public class ConfirmedCloseWindow extends JFrame {

    public ConfirmedCloseWindow() {

        addWindowListener(new WindowConfirmedCloseAdapter());
    }

    private void closeWindow() {
        processWindowEvent(new WindowEvent(this, WindowEvent.WINDOW_CLOSING));
    }
}

Sulla base delle risposte già fornite qui, questo è il modo in cui l'ho implementato:

JFrame frame= new JFrame()
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

// frame stuffs here ...

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

JFrame fa chiudere l'evento e alla chiusura, esce.

Questa risposta è stata data da Alex e vorrei raccomandarla. Ha funzionato per me e un'altra cosa è semplice e così semplice.

setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

Devi inserire la chiamata nella coda dei messaggi AWT in modo che tutti i tempi avvengano correttamente, altrimenti non invierà la sequenza di eventi corretta, specialmente in un programma multi-thread. Al termine, è possibile gestire la sequenza di eventi risultante esattamente come si farebbe se l'utente avesse fatto clic sul pulsante [x] per un JFrame decorato con SO integrato.

public void closeWindow()
{
    if(awtWindow_ != null) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
            }
        });
    }
}

Ho provato questo, scrivi il tuo codice per l'evento formWindowClosing () .

 private void formWindowClosing(java.awt.event.WindowEvent evt) {                                   
    int selectedOption = JOptionPane.showConfirmDialog(null,
            "Do you want to exit?",
            "FrameToClose",
            JOptionPane.YES_NO_OPTION);
    if (selectedOption == JOptionPane.YES_OPTION) {
        setVisible(false);
        dispose();
    } else {
        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
    }
}    

Questo chiede all'utente se desidera uscire dal Frame o dall'applicazione.

Pubblicando ciò che era nel corpo della domanda come risposta in CW.

Volevo condividere i risultati, principalmente derivati ??dal seguente link di camickr. Fondamentalmente ho bisogno di lanciare un WindowEvent.WINDOW_CLOSING nella coda degli eventi dell'applicazione. Ecco una sinossi di come appare la soluzione

// closing down the window makes sense as a method, so here are
// the salient parts of what happens with the JFrame extending class ..

    public class FooWindow extends JFrame {
        public FooWindow() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setBounds(5, 5, 400, 300);  // yeah yeah, this is an example ;P
            setVisible(true);
        }
        public void pullThePlug() {
                WindowEvent wev = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
                Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
        }
    }

// Here's how that would be employed from elsewhere -

    // someplace the window gets created ..
    FooWindow fooey = new FooWindow();
    ...
    // and someplace else, you can close it thusly
    fooey.pullThePlug();

Se non si desidera che l'applicazione venga chiusa alla chiusura di un JFrame, uso:     setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

invece di:     setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

Dalla documentazione:

DO_NOTHING_ON_CLOSE (definito in WindowConstants) : non fare nulla; richiede che il programma gestisca l'operazione nel metodo windowClosing di un oggetto WindowListener registrato.

HIDE_ON_CLOSE (definito in WindowConstants) : nasconde automaticamente il frame dopo aver richiamato gli oggetti WindowListener registrati.

DISPOSE_ON_CLOSE (definito in WindowConstants) : nasconde e getta automaticamente il frame dopo aver richiamato gli oggetti WindowListener registrati.

EXIT_ON_CLOSE (definito in JFrame) : esci dall'applicazione usando il metodo di uscita Sistema. Usalo solo nelle applicazioni.

potrebbe ancora essere utile: Puoi usare setVisible (false) sul tuo JFrame se vuoi visualizzare di nuovo lo stesso frame. Altrimenti chiama dispose () per rimuovere tutte le risorse della schermata nativa.

copiato da Peter Lang

https://stackoverflow.com/a/1944474/3782247

 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top