Comment programmer la fermeture d'un JFrame

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

j'ai mon opération de fermeture par défaut réglée comme je veux, via:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

C'est exactement ce que je veux avec les mêmes contrôles. Cette question n'est pas de cela.

ce que je veux vraiment faire est de faire en sorte que L'interface graphique se comporte de la même manière qu'une pression sur le bouton X le ferait se comporter.

supposez que je devais étendre WindowAdaptor et ensuite ajouter une instance de mon adaptateur comme un auditeur via addWindowListener() . J'aimerais voir la même séquence d'appels par windowDeactivated() , windowClosing() , et windowClosed() que celle qui se produirait avec le bouton de fermeture X . Pas tant de briser la fenêtre que de lui dire de se déchirer, pour ainsi dire.

222
demandé sur Nathan 2009-08-05 22:24:30

18 réponses

si vous voulez que l'interface graphique se comporte comme si vous aviez cliqué sur le bouton X fermer, alors vous devez envoyer un événement de fermeture de fenêtre au Window . Le ExitAction de fermer une Application vous permet d'ajouter cette fonctionnalité à un élément de menu ou à tout composant qui utilise Action facilement.

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
276
répondu camickr 2016-04-01 00:01:31
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

pas trop délicat.

118
répondu Alex 2009-08-05 19:42:05

si par Alt-F4 ou X vous voulez dire" quitter L'Application immédiatement sans tenir compte de ce que D'autres fenêtres ou fils sont en cours d'exécution", alors System.exit(...) fera exactement ce que vous voulez d'une manière très abrupte, brute-force, et peut-être problématique.

si par Alt-F4 ou X vous voulez dire cacher la fenêtre, alors frame.setVisible(false) est la façon dont vous" fermez " la fenêtre. La fenêtre va continuer à consommer des ressources/mémoire mais peut être rendue visible à nouveau très rapidement.

si par Alt-F4 ou X vous voulez dire cacher la fenêtre et disposer de toutes les ressources qu'elle consomme, alors frame.dispose() est la façon dont vous" fermez " la fenêtre. Si le cadre était la dernière fenêtre visible et qu'il n'y a pas d'autres threads Non-démon en cours d'exécution, le programme se terminera. Si vous affichez la fenêtre à nouveau, elle devra réinitialiser toutes les ressources natives (tampon graphique, poignées de fenêtre, etc.).

dispose() pourrait être plus proche du comportement que vous voulez vraiment. Si votre application a plusieurs fenêtres ouvertes, voulez-vous Alt-F4 ou X pour quitter l'application ou juste fermer la fenêtre active?

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

24
répondu James Schek 2014-06-01 03:39:08

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

frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);

alors vous devez changer votre pullThePlug() méthode pour être

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 la seule façon qui joue bien avec le WindowListener et JFrame.DO_NOTHING_ON_CLOSE .

16
répondu Gazi Alankus 2011-03-28 04:27:02

quitter le processus D'exécution Java est très facile, fondamentalement, vous devez faire juste deux choses simples:

  1. Appel de méthode java System.exit(...) à l'application du point de quitter. Par exemple, si votre application est basée sur un cadre, vous pouvez ajouter l'auditeur WindowAdapter et appeler System.exit(...) dans sa méthode windowClosing(WindowEvent e) .

Note: vous devez appeler System.exit(...) sinon votre programme est une erreur.

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

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

** voici un exemple plus simple ( JFrame ) qui vous montre comment appeler méthode de sortie

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);
   }
}
9
répondu Jaimin Patel 2018-02-07 06:13:02

voici vos options:

System.exit(0); // stop program
frame.dispose(); // close window
frame.setVisible(false); // hide window
7
répondu Arin 2017-08-06 15:52:32

non seulement pour fermer le JFrame mais aussi pour déclencher des événements WindowListener, essayez ceci:

myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
6
répondu niranaam 2014-08-27 11:53:20

setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

ferme non seulement la cellule, mais aussi l'ensemble de l'application, d'où "EXIT ON CLOSE"

pour obtenir le même résultat, vous devez effectivement quitter l'application, pour cela simplement appeler

 System.exit(0);

L'effet est exactement le même.

6
répondu OscarRyz 2018-04-18 09:16:42

la meilleure façon de fermer un cadre oscillant de façon programmatique est de le faire se comporter comme il le ferait lorsque le bouton" X " est appuyé. Pour ce faire, vous devrez implémenter WindowAdapter qui convient à vos besoins et définir l'opération de fermeture par défaut de frame pour ne rien faire (DO_NOTHING_ON_CLOSE).

initialisez votre image 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 programmatiquement en lui envoyant L'événement WINDOW_CLOSING, comme ceci:

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

cela fermera le cadre comme le bouton" X " a été pressé.

5
répondu stjepano 2014-08-27 11:51:54

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

la fenêtre a un adaptateur de fenêtre qui commute l'opération de fermeture par défaut à EXIT_ON_CLOSE ou DO_NOTHING_ON_CLOSE dépendant de votre réponse dans le OptionDialog .

la méthode closeWindow de la ConfirmedCloseWindow déclenche un événement de fermeture de fenêtre et peut être utilisée n'importe où i.e. comme 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));
    }
}
4
répondu rkd 2012-10-16 21:59:53

basé sur les réponses déjà fournies ici, c'est la façon dont je l'ai mis en œuvre:

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

// frame stuffs here ...

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

le JFrame permet à l'événement de se fermer et à la fermeture, sort.

4
répondu Megatron 2014-06-03 17:08:51

si vous ne voulez vraiment pas que votre application se termine quand un JFrame est fermé alors,

utilisation: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

au lieu de: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

voici un résumé de ce à quoi ressemble la solution,

 myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
4
répondu Harita M 2016-09-01 06:01:57

Cette réponse a été donnée par Alex et je voudrais le recommander. Ça a marché pour moi et autre chose, c'est simple et si simple.

setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object
4
répondu Humphrey 2016-11-13 11:05:21

vous devez insérer l'appel dans la file D'attente de messages AWT pour que tout le timing se passe correctement, sinon il ne va pas envoyer la séquence d'événements correcte, en particulier dans un programme multi-threadé. Lorsque cela est fait, vous pouvez gérer la séquence d'événements résultante exactement comme vous le feriez si l'Utilisateur a cliqué sur le bouton [x] pour un JFrame décoré avec OS.

public void closeWindow()
{
    if(awtWindow_ != null) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
            }
        });
    }
}
3
répondu peterk 2012-12-27 17:21:28

affichant ce qui était dans le corps des questions comme réponse de CW.

a voulu partager les résultats, principalement dérivés du lien de camickr. Fondamentalement, je dois jeter un WindowEvent.WINDOW_CLOSING à la file d'attente d'événements de l'application. Voici un résumé de ce à quoi ressemble la solution

// 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();
2
répondu Vogel612 2014-08-27 11:40:45

si vous ne voulez pas que votre application se termine quand un JFrame est fermé, utiliser: setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE)

au lieu de: setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

de la documentation:

DO_NOTHING_ON_CLOSE (defined in WindowConstants) : ne rien faire; exiger le programme pour gérer l'opération dans la méthode windowClosing d'un objet WindowListener enregistré.

HIDE_ON_CLOSE (defined in WindowConstants) : Masquer automatiquement le cadre après avoir invoqué tout objet WindowListener enregistré.

DISPOSE_ON_CLOSE (defined in WindowConstants) : cacher et disposer automatiquement le cadre après avoir invoqué des objets WindowListener enregistrés.

EXIT_ON_CLOSE (defined in JFrame) : Sortir de l'application en utilisant le Système de sortie de la méthode. Utilisez ceci seulement dans les applications.

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

copié de Peter Lang

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

2
répondu Mena Nashaat 2017-05-23 10:31:32

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

cela demande à l'utilisateur s'il veut sortir du cadre ou de l'Application.

2
répondu r_D 2017-07-17 18:16:02
 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
0
répondu Itay Maman 2009-08-05 18:48:59