Question

Quelle est la bonne façon de fermer un JFrame , comme si l'utilisateur avait appuyé sur le bouton de fermeture X ou appuyé sur Alt + F4 (sous Windows)?

J'ai mon opération de fermeture par défaut définie comme je le souhaite, via:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Il fait exactement ce que je veux avec les commandes susmentionnées. Cette question ne concerne pas cela.

Ce que je veux vraiment faire, c'est que l'interface graphique se comporte de la même manière qu'une pression sur le bouton de fermeture X provoquerait son comportement.

Supposons que je devrais étendre WindowAdaptor , puis ajouter une instance de mon adaptateur en tant qu'écouteur via addWindowListener () . Je voudrais voir la même séquence d'appels via windowDeactivated () , windowClosing () et windowClosed () comme cela se produirait avec le < bouton de fermeture code> X . Pas tellement de déchirer la fenêtre que de lui dire de se déchirer, pour ainsi dire.

Était-ce utile?

La solution

Si vous souhaitez que l'interface graphique se comporte comme si vous aviez cliqué sur le bouton de fermeture X , vous devez envoyer un événement de fermeture de fenêtre à Window . ExitAction à partir de Fermeture d'une application vous permet d’ajouter cette fonctionnalité à un élément de menu ou à tout composant utilisant Action facilement.

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

Autres conseils

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

Pas trop compliqué.

Si, par Alt-F4 ou X, vous entendez "Quitter immédiatement l'application sans tenir compte de ce que les autres fenêtres ou threads exécutent", alors System.exit (...) fera exactement ce que vous voulez d'une manière très abrupte, brutale et éventuellement problématique.

Si par Alt-F4 ou X, vous voulez masquer la fenêtre, alors frame.setVisible (false) est le moyen par lequel vous "fermez" la fenêtre. La fenêtre continuera de consommer des ressources / de la mémoire mais pourra redevenir visible très rapidement.

Si par Alt-F4 ou X, vous voulez masquer la fenêtre et supprimer toutes les ressources qu'elle consomme, alors frame.dispose () est le moyen par lequel vous "fermez" la fenêtre. Si le cadre était la dernière fenêtre visible et qu'aucun autre thread non démon n'est en cours d'exécution, le programme se fermera. Si vous réaffichez la fenêtre, elle devra réinitialiser toutes les ressources natives (tampon graphique, descripteurs de fenêtre, etc.).

dispose () est peut-être le comportement le plus approprié. Si votre application a plusieurs fenêtres ouvertes, voulez-vous que Alt-F4 ou X la quitte ou ferme juste la fenêtre active?

Le didacticiel Java Swing sur les écouteurs de fenêtre peut aider à clarifier les choses pour vous.

Si vous avez fait cela pour vous assurer que l'utilisateur ne peut pas fermer la fenêtre:

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

Vous devez ensuite modifier votre méthode pullThePlug () pour qu'elle soit

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

J’ai trouvé que c’était le seul moyen qui fonctionnait bien avec les éléments WindowListener et JFrame.DO_NOTHING_ON_CLOSE .

Voici vos options:

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

Il est très facile de quitter le processus en cours d'exécution Java. En gros, il suffit de faire deux choses simples:

  1. Appelez la méthode java System.exit (...) au point de fermeture de l'application. Par exemple, si votre application est basée sur des cadres, vous pouvez ajouter le programme d'écoute WindowAdapter et appeler System.exit (...) dans sa méthode windowClosing (WindowEvent e ) .

Remarque: vous devez appeler System.exit (...) sinon votre programme est impliqué dans une erreur.

  1. Éviter les exceptions Java inattendues pour s'assurer que la méthode de sortie peut toujours être appelée. Si vous ajoutez System.exit (...) au bon moment, mais cela ne signifie pas que la méthode peut toujours être appelée, car des exceptions java inattendues peuvent empêcher son appel.

Ceci est fortement lié à vos compétences en programmation.

** Voici un exemple simple (basé sur JFrame ) qui montre comment appeler une méthode d'exit

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

Essayez non seulement de fermer le cadre JFrame, mais aussi de déclencher des événements WindowListener:

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

setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE);

Ferme non seulement le cadre JFrame, mais arrête également l'application dans son ensemble, d'où le message "EXIT ON CLOSE" (EXIT SUR CLOSE)

.

Pour obtenir le même résultat, vous devez quitter l'application. Pour cela, il vous suffit d'appeler

.
 System.exit(0);

L'effet est exactement le même.

Le meilleur moyen de fermer un cadre Swing par programmation consiste à le faire se comporter comme il le ferait lorsque le "X" bouton est enfoncé. Pour ce faire, vous devez implémenter WindowAdapter selon vos besoins et configurer l'opération de fermeture par défaut de frame pour qu'elle ne fasse rien (DO_NOTHING_ON_CLOSE).

Initialisez votre cadre comme ceci:

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

Vous pouvez fermer le cadre par programme en lui envoyant l'événement WINDOW_CLOSING, comme suit:

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

Ceci fermera le cadre comme le "X". bouton a été enfoncé.

Si vous ne voulez vraiment pas que votre application se termine lorsqu'un fichier JFrame est fermé, alors

utiliser: setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);

au lieu de: setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

Voici un résumé de l’apparence de la solution,

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

Cet exemple montre comment réaliser l'opération de fermeture de fenêtre confirmée.

La fenêtre a un adaptateur Windows qui bascule l'opération de fermeture par défaut sur EXIT_ON_CLOSE ou DO_NOTHING_ON_CLOSE en fonction de votre réponse dans OptionDialog .

La méthode closeWindow de ConfirmedCloseWindow déclenche un événement de fenêtre proche et peut être utilisée n'importe où, c'est-à-dire en tant qu'action d'un élément de 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));
    }
}

Sur la base des réponses déjà fournies ici, voici comment je l'ai implémenté:

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

// frame stuffs here ...

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

JFrame obtient la fermeture de l'événement et les ferme à la fermeture.

Cette réponse a été donnée par Alex et je voudrais la recommander. Cela a fonctionné pour moi et une autre chose, c'est simple et tellement simple.

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

Vous devez insérer l'appel dans la file d'attente de messages AWT pour que tout le chronométrage se déroule correctement, sinon la séquence d'événements appropriée ne sera pas envoyée, en particulier dans un programme à plusieurs threads. Ceci fait, vous pourrez gérer la séquence d’événements résultante exactement comme si l’utilisateur avait cliqué sur le bouton [x] pour un JFrame décoré fourni par le système d’exploitation.

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

J'ai essayé ceci, écrivez votre propre code pour l'événement 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);
    }
}    

Ceci demande à l'utilisateur s'il souhaite quitter le cadre ou l'application.

Afficher ce qui était dans le corps de la question en tant que réponse CW.

Je voulais partager les résultats, principalement dérivés du lien suivant sur camickr. Fondamentalement, je dois lancer un WindowEvent.WINDOW_CLOSING dans la file d'attente des événements de l'application. Voici un résumé de la solution proposée

// 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();

Si vous ne souhaitez pas que votre application se termine lorsqu'un fichier JFrame est fermé, utilisation:     setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

au lieu de:     setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

À partir de la documentation:

DO_NOTHING_ON_CLOSE (défini dans WindowConstants) : ne rien faire; demander au programme de gérer l'opération dans la méthode windowClosing d'un objet WindowListener enregistré.

HIDE_ON_CLOSE (défini dans WindowConstants) : masque automatiquement le cadre après l'appel de tout objet WindowListener enregistré.

DISPOSE_ON_CLOSE (défini dans WindowConstants) : masque et supprime automatiquement le cadre après avoir appelé tout objet WindowListener enregistré.

EXIT_ON_CLOSE (défini dans JFrame) : quittez l'application à l'aide de la méthode de sortie System. Utilisez-le uniquement dans les applications.

pourrait encore être utile: Vous pouvez utiliser setVisible (false) sur votre JFrame si vous souhaitez afficher à nouveau le même cadre. Sinon, appelez dispose () pour supprimer toutes les ressources d'écran natives.

copié de Peter Lang

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

 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top