web-dev-qa-db-fra.com

Comment fermer par programme un JFrame

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

Mon opération de fermeture par défaut est définie comme je le souhaite, via:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Il fait exactement ce que je veux avec les contrôles susmentionnés. Cette question n'est pas à ce sujet.

Ce que je veux vraiment faire, c’est que l’interface graphique se comporte de la même manière qu’un appui sur le bouton X close le ferait se comporter.

Supposons que je devrais étendre WindowAdaptor puis ajouter une instance de mon adaptateur en tant qu'auditeur via addWindowListener(). J'aimerais voir la même séquence d'appels via windowDeactivated(), windowClosing() et windowClosed() que si le bouton X Close était fermé. Pas tellement de déchirer la fenêtre que de lui dire de se déchirer, pour ainsi dire.

235
JustJeff

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

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
304
camickr
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object

Pas trop compliqué.

126
Alex

Si par Alt-F4 ou X, vous voulez dire "Quitter immédiatement l'application sans se soucier des autres fenêtres ou threads en cours d'exécution", 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 dire cacher la fenêtre, alors frame.setVisible(false) est comment vous "fermez" la fenêtre. La fenêtre continuera à consommer des ressources/de la mémoire mais pourra être rendue visible très rapidement.

Si par Alt-F4 ou X, vous voulez dire cacher la fenêtre et supprimer toutes les ressources qu’elle consomme, alors frame.dispose() vous permet de "fermer" 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() pourrait être le comportement le plus approprié. Si votre application a plusieurs fenêtres ouvertes, voulez-vous que Alt-F4 ou X quitte l'application ou ferme simplement la fenêtre active?

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

25
James Schek

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

Ensuite, vous devriez changer votre méthode pullThePlug() 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 le seul moyen de jouer à Nice avec les WindowListener et JFrame.DO_NOTHING_ON_CLOSE.

14
Gazihan Alankus

Voici vos options:

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

Quitter le processus en cours de Java est très simple. En gros, il suffit de faire deux choses simples:

  1. Appelez Java method System.exit(...) au point de fermeture de l'application. Par exemple, si votre application est basée sur des images, 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 comporte des erreurs.

  1. Éviter les exceptions inattendues Java pour s'assurer que la méthode exit 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 inattendues Java risquent d'empêcher l'appel de la méthode.

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);
   }
}
8
Jaimin Patel

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

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

setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE));

Non seulement ferme le JFrame, mais ferme l'application entière, d'où "EXIT ON CLOSE"

Pour obtenir le même résultat, vous devez quitter efficacement l'application. Pour cela, appelez simplement

 System.exit(0);

L'effet est exactement le même.

5
OscarRyz

Si vous ne voulez vraiment pas que votre application se termine à la fermeture d'un fichier JFrame,

utiliser: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

au lieu de: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

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

 myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
4
Harita M

Le meilleur moyen de fermer un cadre Swing par programme consiste à le faire se comporter comme si le bouton "X" était 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);

Cela fermera le cadre comme si le bouton "X" avait été enfoncé.

4
stjepano

D'après les 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 permet à l'événement de se fermer et, à la fermeture, de sortir.

3
Megatron

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
3
Humphrey

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_CLOSEou DO_NOTHING_ON_CLOSE en fonction de votre réponse dans le OptionDialog.

La méthode closeWindow de la ConfirmedCloseWindow déclenche un événement de fenêtre proche et peut être utilisée n’importe où, c’est-à-dire 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));
    }
}
3
rkd

Vous devez insérer l'appel dans la file d'attente de messages AWT pour que tout le minutage se déroule correctement, sinon la séquence d'événements appropriée ne sera pas envoyée, en particulier dans un programme multithread. Ceci fait, vous pouvez 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));
            }
        });
    }
}
2
peterk

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.

2
r_D

Si vous ne souhaitez pas que votre application se ferme lors de la fermeture d'une image JFrame, utilisez: setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE).

au lieu de: setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);

De la documentation:

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

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

DISPOSE_ON_CLOSE (defined in WindowConstants): Masque et supprime automatiquement le cadre après avoir appelé un objet WindowListener enregistré.

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

peut 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

1
Mena Nashaat

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. En gros, 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.

// 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();
1
Vogel612
 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
0
Itay Maman