首页 文章

如何以编程方式关闭JFrame

提问于
浏览
225

JFrame 关闭的正确方法是什么,就像用户按下 X 关闭按钮,或按下Alt F4(在Windows上)一样?

我通过以下方式设置我的默认关闭操作:

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

它完全符合我想要的上述控件 . 这个问题与此无关 .

我真正想要做的是使GUI的行为与按 X 关闭按钮会导致它的行为相同 .

假设我要扩展 WindowAdaptor ,然后通过 addWindowListener() 添加我的适配器实例作为监听器 . 我希望通过 windowDeactivated()windowClosing()windowClosed() 看到与 X 关闭按钮相同的调用序列 . 可以这么说,撕毁窗户就像告诉它撕裂自己一样 .

18 回答

  • 0

    不仅要关闭JFrame而且要触发WindowListener事件,请尝试以下方法:

    myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
    
  • 2

    如果您不希望应用程序在关闭JFrame时终止,请使用:setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)

    而不是:setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    从文档:

    DO_NOTHING_ON_CLOSE (defined in WindowConstants) :什么都不做;要求程序在已注册的WindowListener对象的windowClosing方法中处理该操作 .

    HIDE_ON_CLOSE (defined in WindowConstants) :在调用任何已注册的WindowListener对象后自动隐藏框架 .

    DISPOSE_ON_CLOSE (defined in WindowConstants) :在调用任何已注册的WindowListener对象后自动隐藏和处置框架 .

    EXIT_ON_CLOSE (defined in JFrame) :使用系统退出方法退出应用程序 . 仅在应用程序中使用它 .

    可能仍然有用:如果要再次显示相同的帧,可以在JFrame上使用 setVisible(false) . 否则,请调用 dispose() 以删除所有本机屏幕资源 .

    _011_从Peter Lang复制

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

  • 2
    setVisible(false); //you can't see me!
    dispose(); //Destroy the JFrame object
    

    不太狡猾 .

  • 4

    作为CW答案发布问题正文中的内容 .

    想要分享结果,主要来自以下camickr的链接 . 基本上我需要在应用程序's event queue. Here'上抛出 WindowEvent.WINDOW_CLOSING ,这是解决方案的概要

    // 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();
    
  • 6

    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

    不仅关闭JFrame而且关闭整个应用程序,因此“退出关闭”

    要实现相同的结果,您必须有效地退出应用程序,因为这只是调用

    System.exit(0);
    

    效果完全一样 .

  • 6

    如果用Alt-F4或X表示"Exit the Application Immediately Without Regard for What Other Windows or Threads are Running",则 System.exit(...) 将以非常突然,蛮力和可能有问题的方式完成您想要的操作 .

    如果按Alt-F4或X表示隐藏窗口,那么 frame.setVisible(false) 就是你如何"close"窗口 . 窗口将继续消耗资源/内存,但可以非常快速地再次显示 .

    如果用Alt-F4或X表示隐藏窗口并处理它正在消耗的任何资源,那么 frame.dispose() 就是你如何"close"窗口 . 如果框架是最后一个可见窗口并且没有其他非守护程序线程在运行,程序将退出 . 如果再次显示该窗口,则必须再次重新初始化所有本机资源(图形缓冲区,窗口句柄等) .

    dispose() 可能最接近您真正想要的行为 . 如果您的应用程序打开了多个窗口,您是否希望Alt-F4或X退出应用程序或关闭活动窗口?

    Java Swing Tutorial on Window Listeners可能有助于为您澄清事情 .

  • 5

    这是您的选择:

    System.exit(0); // stop program
    frame.dispose(); // close window
    frame.setVisible(false); // hide window
    
  • 24

    以编程方式关闭Swing框架的最佳方法是使其行为与按下“X”按钮时的行为相同 . 要做到这一点,您需要实现适合您需要的WindowAdapter,并设置框架的默认关闭操作以不执行任何操作(DO_NOTHING_ON_CLOSE) .

    像这样初始化你的框架:

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

    您可以通过发送WINDOW_CLOSING事件以编程方式关闭框架,如下所示:

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

    这将关闭框架,就像按下“X”按钮一样 .

  • 2

    此示例显示如何实现确认的窗口关闭操作 .

    该窗口有一个Window适配器,它根据您在 OptionDialog 中的答案将默认关闭操作切换为 EXIT_ON_CLOSEDO_NOTHING_ON_CLOSE .

    ConfirmedCloseWindowcloseWindow 方法触发关闭窗口事件,可以在任何地方使用,即作为菜单项的动作

    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
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    
  • 4

    如果您这样做是为了确保用户无法关闭窗口:

    frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    

    然后你应该改变你的 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); 
    }
    

    我发现这是与 WindowListenerJFrame.DO_NOTHING_ON_CLOSE 一起玩的唯一方式 .

  • 280

    退出Java运行过程非常简单,基本上你只需要做两件简单的事情:

    • 在应用程序的退出点调用java方法 System.exit(...) . 例如,如果您的应用程序是基于帧的,则可以添加侦听器 WindowAdapter 并在其方法 windowClosing(WindowEvent e) 中调用 System.exit(...) .

    注意:您必须调用 System.exit(...) 否则您的程序会出错 .

    • 避免意外的java异常以确保exit方法总是可以调用 . 如果在正确的位置添加 System.exit(...) ,但这并不意味着可以始终调用该方法,因为意外的java异常可能会阻止调用该方法 .

    这与您的编程技巧密切相关 .

    **以下是一个最简单的示例(基于 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);
       }
    }
    
  • 4

    如果你真的不希望你的应用程序在关闭JFrame时终止,那么,

    使用: setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    而不是: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    这是解决方案的概要,

    myFrame.dispatchEvent(new WindowEvent(myFrame, WindowEvent.WINDOW_CLOSING));
    
  • 8

    基于此处已提供的答案,这是我实现它的方式:

    JFrame frame= new JFrame()
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    // frame stuffs here ...
    
    frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
    

    JFrame使事件关闭,并在关闭时退出 .

  • 120

    我试过这个,为 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);
        }
    }
    

    这会询问用户是否要退出框架或应用程序 .

  • 3

    这个答案是亚历克斯给出的,我想推荐它 . 它对我有用,而另一件事则很简单,也很简单 .

    setVisible(false); //you can't see me!
    dispose(); //Destroy the JFrame object
    
  • 16

    如果您希望GUI的行为就像您单击 X 关闭按钮一样,则需要将窗口关闭事件分派给 Window . 来自Closing An ApplicationExitAction 允许您将此功能添加到菜单项或任何轻松使用 Action 的组件 .

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

    您必须将调用插入到AWT消息队列中,以便所有时间都正确发生,否则它将不会调度正确的事件序列,尤其是在多线程程序中 . 完成此操作后,您可以完全按照用户单击操作系统提供的装饰JFrame的[x]按钮的方式处理生成的事件序列 .

    public void closeWindow()
    {
        if(awtWindow_ != null) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    awtWindow_.dispatchEvent(new WindowEvent(awtWindow_, WindowEvent.WINDOW_CLOSING));
                }
            });
        }
    }
    

相关问题