简体   繁体   English

如何以编程方式关闭JFrame

[英]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 . 我发现这是与WindowListenerJFrame.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运行过程非常容易,基本上,您只需要做两件事即可:

  1. Call java method System.exit(...) at at application's quit point. 在应用程序的退出点调用Java方法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(...)否则您的程序会出错。

  1. Avoiding unexpected java exceptions to make sure the exit method can be called always. 避免意外的Java异常,以确保可以始终调用exit方法。 If you add 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_CLOSEDO_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()删除所有本机屏幕资源。

copied from Peter Lang 摘自Peter Lang

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM