Quelle est la manière correcte de fermer un JFrame
, comme si l’utilisateur avait JFrame
sur le bouton de fermeture X
ou sur Alt + F4 (sous Windows)?
J’ai ma fermeture par défaut 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 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 X
fermer le ferait se comporter.
Supposons que je WindowAdaptor
étendre WindowAdaptor
, puis append une instance de mon adaptateur en tant addWindowListener()
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 X
Pas tellement déchirer la fenêtre que lui dire de se déchirer, pour ainsi dire.
Si vous souhaitez que l’interface graphique se comporte comme si vous cliquiez sur le bouton Fermer X
vous devez envoyer un événement de fermeture de fenêtre à la Window
. L’ ExitAction
de la fermeture d’une application vous permet d’append cette fonctionnalité à un élément de menu ou à tout composant utilisant facilement Action
s.
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
setVisible(false); //you can't see me! dispose(); //Destroy the JFrame object
Pas trop compliqué.
Si, par Alt-F4 ou X, vous voulez dire “Quitter l’application immédiatement sans tenir compte de ce que les autres fenêtres ou threads exécutent”, alors System.exit(...)
fera exactement ce que vous voulez dans une brute-force brusque, et peut-être la mode problématique.
Si, par Alt-F4 ou X, vous voulez dire cacher la fenêtre, alors frame.setVisible(false)
est la manière dont vous “fermez” la fenêtre. La fenêtre continuera à consumr des ressources / mémoire mais pourra être rendue visible très rapidement.
Si, par Alt-F4 ou X, vous voulez dire cacher la fenêtre et éliminer les ressources qu’elle consum, alors frame.dispose()
est la manière dont vous “fermez” la fenêtre. Si le cadre était la dernière fenêtre visible et qu’aucun autre thread non-démon ne s’exécute, le programme se terminera. Si vous affichez à nouveau la fenêtre, elle devra réinitialiser toutes les ressources natives (tampon graphique, poignées de fenêtre, etc.).
dispose()
pourrait être le plus proche du comportement que vous voulez vraiment. Si votre application a plusieurs fenêtres ouvertes, voulez-vous que Alt-F4 ou X ferme l’application ou ferme la fenêtre active?
Le tutoriel Java Swing sur les écouteurs Windows peut vous aider à clarifier les choses.
Si vous l’avez fait, assurez-vous 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 la seule façon de jouer avec WindowListener
et JFrame.DO_NOTHING_ON_CLOSE
.
Quitter le processus d’exécution Java est très simple. En gros, vous devez faire deux choses simples:
System.exit(...)
au sharepoint fermeture de l’application. Par exemple, si votre application est basée sur une trame, vous pouvez append l’écouteur WindowAdapter
et appeler System.exit(...)
intérieur de sa méthode windowClosing(WindowEvent e)
. Note: vous devez appeler System.exit(...)
sinon votre programme est une erreur.
System.exit(...)
au bon endroit, mais cela ne signifie pas que la méthode peut toujours être appelée, car des exceptions Java inattendues peuvent empêcher l’appel de la méthode. Ceci est fortement lié à vos compétences en programmation.
** Voici un exemple le plus simple (basé sur JFrame
) qui vous montre comment appeler la 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(Ssortingng[] args) { ExitApp app=new ExitApp(); app.setBounds(133,100,532,400); app.setVisible(true); } }
Voici vos options:
System.exit(0); // stop program frame.dispose(); // close window frame.setVisible(false); // hide window
Non seulement pour fermer JFrame mais aussi pour déclencher des événements WindowListener, essayez ceci:
myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE);
Non seulement ferme JFrame mais les fermetures de toute l’application, donc “EXIT ON CLOSE”
Pour obtenir le même résultat, vous devez quitter efficacement l’application, car il suffit d’appeler
System.exit(0);
L’effet est exactement le même.
La meilleure façon de fermer un cadre Swing par programmation est de le faire se comporter comme le ferait le bouton “X”. Pour ce faire, vous devrez implémenter WindowAdapter qui convient à vos besoins et définir l’opération de fermeture par défaut du cadre pour ne rien faire (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 programmation 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é appuyé.
Cet exemple montre comment réaliser l’opération de fermeture de fenêtre confirmée.
La fenêtre possède un adaptateur Windows qui bascule l’opération de fermeture par défaut sur EXIT_ON_CLOSE
ou DO_NOTHING_ON_CLOSE
fonction de votre réponse dans OptionDialog
.
La méthode closeWindow
de ConfirmedCloseWindow
déclenche un événement de fenêtre de fermeture et peut être utilisée n’importe où, par exemple 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, voici comment je les ai mises 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 obtient la fermeture de l’événement et à la fermeture, quitte.
Si vous ne voulez vraiment pas que votre application se termine lorsqu’un JFrame est fermé, alors,
utilisez: 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));
Cette réponse a été donnée par Alex et je voudrais le recommander. Cela a fonctionné pour moi et une autre chose, c’est simple et simple.
setVisible(false); //you can't see me! dispose(); //Destroy the JFrame object
Vous devez insérer l’appel dans la queue des messages AWT pour que tout le minutage se passe correctement, sinon il ne dissortingbuera pas la séquence d’événements correcte, en particulier dans un programme multithread. Lorsque cela est fait, vous pouvez gérer la séquence d’événements résultante exactement comme vous le feriez si l’utilisateur avait cliqué sur le bouton [x] pour obtenir 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)); } }); } }
Afficher ce qui était dans le corps de la question comme réponse CW.
Je voulais partager les résultats, principalement issus du lien suivant. Fondamentalement, je dois lancer un WindowEvent.WINDOW_CLOSING
dans la queue 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();
Si vous ne souhaitez pas que votre application se termine lorsqu’un JFrame est fermé, 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 faites rien; nécessite que le programme gère l’opération dans la méthode windowClosing d’un object WindowListener enregistré.
HIDE_ON_CLOSE (defined in WindowConstants)
: masque automatiquement le cadre après l’appel de tout object WindowListener enregistré.
DISPOSE_ON_CLOSE (defined in WindowConstants)
: masquez et DISPOSE_ON_CLOSE (defined in WindowConstants)
automatiquement le cadre après avoir appelé tous les objects WindowListener enregistrés.
EXIT_ON_CLOSE (defined in JFrame)
: EXIT_ON_CLOSE (defined in JFrame)
l’application à l’aide de la méthode de sortie du système. Utilisez ceci 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.
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 souhaite quitter le cadre ou l’application.
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);