[英]How to programmatically close a JFrame
What's the correct way to get a JFrame
to close, the same as if the user had hit the X
close button, or pressed Alt + F4 (on Windows)? 关闭
JFrame
的正确方法是什么,就像用户按下X
关闭按钮或按下Alt + F4 键 (在Windows上)一样?
I have my default close operation set the way I want, via: 我通过以下方式设置了我想要的默认关闭操作:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
It does exactly what I want with the aforementioned controls. 它完全符合我想要的上述控件的功能。 This question isn't about that.
这个问题不是关于这个的。
What I really want to do is cause the GUI to behave in the same way as a press of X
close button would cause it to behave. 我真正想做的是使GUI的行为与按
X
关闭按钮的行为相同。
Suppose I were to extend WindowAdaptor
and then add an instance of my adaptor as a listener via addWindowListener()
. 假设我要扩展
WindowAdaptor
,然后通过addWindowListener()
适配器的实例添加为侦听器。 I would like to see the same sequence of calls through windowDeactivated()
, windowClosing()
, and windowClosed()
as would occur with the X
close button. 我希望通过
windowDeactivated()
, windowClosing()
和windowClosed()
看到与X
关闭按钮相同的调用序列。 Not so much tearing up the window as telling it to tear itself up, so to speak. 可以说,与其说是要把窗户自己撕开,还不如说是要撕开窗户。
If you want the GUI to behave as if you clicked the X
close button then you need to dispatch a window closing event to the Window
. 如果希望GUI像单击
X
关闭按钮一样工作,则需要向Window
调度一个窗口关闭事件。 The ExitAction
from Closing An Application allows you to add this functionality to a menu item or any component that uses Action
s easily. 通过关闭应用程序的
ExitAction
,您可以将此功能添加到菜单项或使用Action
的任何组件中。
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object
Not too tricky. 不太棘手。
If by Alt-F4 or X you mean "Exit the Application Immediately Without Regard for What Other Windows or Threads are Running", then System.exit(...)
will do exactly what you want in a very abrupt, brute-force, and possibly problematic fashion. 如果用Alt-F4或X表示“不考虑正在运行的其他Windows或线程正在运行而立即退出应用程序”,那么
System.exit(...)
将以一种非常突然的蛮力来完全满足您的要求,甚至可能是有问题的时尚。
If by Alt-F4 or X you mean hide the window, then frame.setVisible(false)
is how you "close" the window. 如果按Alt-F4或X表示隐藏窗口,则
frame.setVisible(false)
是“关闭”窗口的方式。 The window will continue to consume resources/memory but can be made visible again very quickly. 该窗口将继续消耗资源/内存,但可以很快使其再次可见。
If by Alt-F4 or X you mean hide the window and dispose of any resources it is consuming, then frame.dispose()
is how you "close" the window. 如果用Alt-F4或X表示隐藏窗口并处置其消耗的任何资源,则
frame.dispose()
是“关闭”窗口的方式。 If the frame was the last visible window and there are no other non-daemon threads running, the program will exit. 如果该框架是最后一个可见窗口,并且没有其他非守护程序线程在运行,则程序将退出。 If you show the window again, it will have to reinitialize all of the native resources again (graphics buffer, window handles, etc).
如果再次显示该窗口,它将不得不再次重新初始化所有本机资源(图形缓冲区,窗口句柄等)。
dispose()
might be closest to the behavior that you really want. dispose()
可能最接近您真正想要的行为。 If your app has multiple windows open, do you want Alt-F4 or X to quit the app or just close the active window? 如果您的应用程序有多个打开的窗口,您是否要让Alt-F4或X退出应用程序或仅关闭活动窗口?
The Java Swing Tutorial on Window Listeners may help clarify things for you. 有关窗口侦听器的Java Swing教程可能会帮助您澄清一些事情。
If you have done this to make sure the user can't close the window: 如果您这样做是为了确保用户无法关闭窗口:
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
Then you should change your pullThePlug()
method to be 然后,您应该将
pullThePlug()
方法更改为
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);
}
I found this to be the only way that plays nice with the WindowListener
and JFrame.DO_NOTHING_ON_CLOSE
. 我发现这是与
WindowListener
和JFrame.DO_NOTHING_ON_CLOSE
配合使用的唯一方法。
Here would be your options: 这是您的选择:
System.exit(0); // stop program
frame.dispose(); // close window
frame.setVisible(false); // hide window
Exiting from Java running process is very easy, basically you need to do just two simple things: 退出Java运行过程非常容易,基本上,您只需要做两件事即可:
System.exit(...)
at at application's quit point. System.exit(...)
。 For example, if your application is frame based, you can add listener WindowAdapter
and and call System.exit(...)
inside its method windowClosing(WindowEvent e)
. WindowAdapter
并在其方法windowClosing(WindowEvent e)
内调用System.exit(...)
windowClosing(WindowEvent e)
。 Note: you must call System.exit(...)
otherwise your program is error involved. 注意:您必须调用
System.exit(...)
否则您的程序会出错。
System.exit(...)
at right point, but It does not mean that the method can be called always, because unexpected java exceptions may prevent the method from been called. System.exit(...)
,但这并不意味着可以始终调用该方法,因为意外的Java异常可能会阻止该方法被调用。 This is strongly related to your programming skills. 这与您的编程技能密切相关。
** Following is a simplest sample ( JFrame
based) which shows you how to call exit method **以下是最简单的示例(基于
JFrame
),向您展示如何调用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);
}
}
不仅要关闭JFrame,还要触发WindowListener事件,请尝试以下操作:
myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Not only closes the JFrame but the shutdowns the entire application, hence "EXIT ON CLOSE" 不仅关闭JFrame,而且关闭整个应用程序,因此“ EXIT ON CLOSE”
To achieve the same result you have to effectively exit the application, for that simply call 要获得相同的结果,您必须有效退出应用程序,为此只需调用
System.exit(0);
The effect is exactly the same. 效果是完全一样的。
If you really do not want your application to terminate when a JFrame is closed then, 如果您确实不希望在关闭JFrame时终止应用程序,
use : setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
使用:
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
instead of : setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
而不是:
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Here's a synopsis of what the solution looks like, 这是解决方案的概要,
myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
Best way to close a Swing frame programmatically is to make it behave like it would when the "X" button is pressed. 以编程方式关闭Swing框架的最佳方法是使其表现得像按下“ X”按钮时一样。 To do that you will need to implement WindowAdapter that suits your needs and set frame's default close operation to do nothing (DO_NOTHING_ON_CLOSE).
为此,您将需要实现适合您需求的WindowAdapter并将框架的默认关闭操作设置为不执行任何操作(DO_NOTHING_ON_CLOSE)。
Initialize your frame like this: 像这样初始化框架:
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);
}
You can close the frame programmatically by sending it the WINDOW_CLOSING event, like this: 您可以通过发送WINDOW_CLOSING事件来以编程方式关闭框架,如下所示:
WindowEvent closingEvent = new WindowEvent(targetFrame, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closingEvent);
This will close the frame like the "X" button was pressed. 这将像按下“ X”按钮那样关闭框架。
This examples shows how to realize the confirmed window close operation. 本示例说明如何实现确认的窗口关闭操作。
The window has a Window adapter which switches the default close operation to EXIT_ON_CLOSE
or DO_NOTHING_ON_CLOSE
dependent on your answer in the OptionDialog
. 该窗口具有切换默认的关闭操作的窗口适配器
EXIT_ON_CLOSE
或DO_NOTHING_ON_CLOSE
依赖于你的答案OptionDialog
。
The method closeWindow
of the ConfirmedCloseWindow
fires a close window event and can be used anywhere ie as an action of an menu item ConfirmedCloseWindow
closeWindow
方法会触发关闭窗口事件,并且可以在任何地方使用,例如,作为菜单项的操作
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));
}
}
Based on the answers already provided here, this is the way I implemented it: 根据此处已经提供的答案,这是我实现它的方式:
JFrame frame= new JFrame()
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame stuffs here ...
frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
The JFrame gets the event to close and upon closing, exits. JFrame使事件关闭,并在关闭时退出。
This answer was given by Alex and I would like to recommend it. 这个答案是亚历克斯给出的,我想推荐它。 It worked for me and another thing it's straightforward and so simple.
它对我有用,而另一件事则非常简单。
setVisible(false); //you can't see me!
dispose(); //Destroy the JFrame object
You have to insert the call into the AWT message queue so all the timing happens correctly, otherwise it will not dispatch the correct event sequence, especially in a multi-threaded program. 您必须将调用插入到AWT消息队列中,以便所有计时都正确发生,否则它将不会分派正确的事件序列,尤其是在多线程程序中。 When this is done you may handle the resulting event sequence exactly as you would if the user has clicked on the [x] button for an OS suppled decorated JFrame.
完成此操作后,您可以完全按照用户单击操作系统装饰好的JFrame的[x]按钮时所处理的事件序列来处理结果。
public void closeWindow()
{
if(awtWindow_ != null) {
EventQueue.invokeLater(new Runnable() {
public void run() {
awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
}
});
}
}
I have tried this, write your own code for formWindowClosing() event. 我已经试过了,为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);
}
}
This asks user whether he want to exit the Frame or Application. 这询问用户是否要退出框架或应用程序。
Posting what was in the question body as CW answer. 将问题正文中的内容发布为CW答案。
Wanted to share the results, mainly derived from following camickr's link. 想要分享结果,主要来自以下camickr的链接。 Basically I need to throw a
WindowEvent.WINDOW_CLOSING
at the application's event queue. 基本上,我需要在应用程序的事件队列中抛出
WindowEvent.WINDOW_CLOSING
。 Here's a synopsis of what the solution looks like 这是解决方案的概要
// 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();
If you do not want your application to terminate when a JFrame is closed, use: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE) 如果您不希望应用程序在JFrame关闭时终止,请使用:setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)
instead of: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 而不是:setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
From the documentation: 从文档中:
DO_NOTHING_ON_CLOSE (defined in WindowConstants)
: Don't do anything; DO_NOTHING_ON_CLOSE (defined in WindowConstants)
:什么都不做; require the program to handle the operation in the windowClosing method of a registered WindowListener object. 要求程序处理注册的WindowListener对象的windowClosing方法中的操作。
HIDE_ON_CLOSE (defined in WindowConstants)
: Automatically hide the frame after invoking any registered WindowListener objects. HIDE_ON_CLOSE (defined in WindowConstants)
:调用任何已注册的WindowListener对象后自动隐藏框架。
DISPOSE_ON_CLOSE (defined in WindowConstants)
: Automatically hide and dispose the frame after invoking any registered WindowListener objects. DISPOSE_ON_CLOSE (defined in WindowConstants)
:调用任何已注册的WindowListener对象后,自动隐藏和处置框架。
EXIT_ON_CLOSE (defined in JFrame)
: Exit the application using the System exit method. EXIT_ON_CLOSE (defined in JFrame)
:使用系统退出方法退出应用程序。 Use this only in applications. 仅在应用程序中使用它。
might still be useful: You can use setVisible(false)
on your JFrame if you want to display the same frame again. 可能仍然有用:如果要再次显示同一帧,可以在JFrame上使用
setVisible(false)
。 Otherwise call dispose()
to remove all of the native screen resources. 否则,调用
dispose()
删除所有本机屏幕资源。
https://stackoverflow.com/a/1944474/3782247 https://stackoverflow.com/a/1944474/3782247
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.