当JDialog是主窗口时,正确关闭Java程序的方法

8

我在我的应用程序中使用JDialog作为主窗口(最初是JFrame,但它在任务栏中显示,这不是我想要的)。

目前我正在执行以下操作:

setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

当我点击退出按钮时:

frame.dispose();

但是这个过程似乎仍然停留在后台。

JFrame拥有JFrame.EXIT_ON_CLOSE,看起来可以满足我的需求。

我该如何正确地关闭我的应用程序?

6个回答

19

你需要添加一个WindowListener,在对话框关闭时执行System.exit(0)。

JDialog dialog = ...;
dialog.addWindowListener(new WindowAdapter() { 
    @Override public void windowClosed(WindowEvent e) { 
      System.exit(0);
    }
  });

当然,在你按下退出按钮后使用System.exit(0)仍然是必要的(这是在本主题中其他地方提出的建议)。


1
这就是它。在我的情况下,我们使用 JPanel 扩展了 JDialog,因此我无法直接调用 addWindowListerner。但由于我们将对话框扩展为 JDialog,我能够调用 super.addWindowListener... 并且它有效。 - rchrd

6

你可以添加

  System.exit(0);

您可以在dispose()代码行后面立即结束程序。


我以为那会关闭整个JVM。它只会关闭当前应用程序吗? - jax

3
考虑使用未装饰的JWindow,但这有点复杂,因为JWindow需要从父级JFrame进行初始化(只需存在即可,没有其他要求)。
更好的方法是添加WindowListener,所有事件/操作都将被重定向/管理这种方式

1

你知道EXIT_ON_CLOSE字段也被JDialog继承了,对吧?

正如@camickr所提到的,EXIT_ON_CLOSE不是JDialog类的setDefaultCloseOperation方法的有效值。根据API所述,

设置默认关闭操作,当用户触发“关闭”对话框时会发生。您必须指定以下选项之一:
  • DO_NOTHING_ON_CLOSE(在WindowConstants中定义):不做任何事情;要求程序在已注册的WindowListener对象的windowClosing方法中处理该操作。
  • HIDE_ON_CLOSE(在WindowConstants中定义):在调用任何注册的WindowListener对象之后自动隐藏对话框。
  • DISPOSE_ON_CLOSE(在WindowConstants中定义):在调用任何已注册的WindowListener对象之后自动隐藏和释放对话框。

如果将EXIT_ON_CLOSE作为参数传递,则会抛出IllegalArgumentException异常。


是的,我使用WindowBuilder创建GUI时没有看到它作为一个可用选项,所以我以为它不可用。谢谢。 - jax
1
-1,真的吗?在JDK6中,根据API EXIT_ON_CLOSE是无效的,当我尝试使用它时,在运行时会出现IllegalArgumentException。如果这是JDK7中的新功能,那么在添加评论表示新功能后,我将取消投票。 - camickr
@mre 这在程序上并不容易实现,所有的顶级容器都有一些问题,称之为错误。可以参考这个链接:https://dev59.com/hG035IYBdhLWcg3wPNdk ,或许可以解决其他问题,也可以参考这个链接:https://dev59.com/T2015IYBdhLWcg3w7wQW。 - mKorbel
@camickr,嗯...你说得对。虽然我还是找不到在API中写这个的地方。我不确定down-vote是否有必要,但这就是你的人品。所以,无论如何。如果你能指出具体的行,说明这个字段是无效的,我会非常感激。但这并不意味着我的答案是错误的。API清楚地显示EXIT_ON_CLOSE是一个继承的字段。我不是故意让这个微妙之处文档不完整。 - mre
@mre,所以赞同错误答案没问题,但是反对错误答案就不行了?反对的意义何在?这个答案是错误和误导性的,这就是我为什么要反对它的原因!setDefaultCloseOperation()方法的有效值在API中有明确的文档说明。我仍然无法相信在我的评论之后这个回答还会得到赞同。顺便说一下,我的回答中没有攻击你的人格,我只是简单地陈述了答案是错误的。我们都会犯错(我知道我经常犯错),我只希望我们能从中学习。 - camickr
@camickr,不确定是谁点了赞,但感谢您指引我正确的方向。其他人可以参考这个链接 - mre

0

你可以尝试下面这段惊人的源代码 -

JDialog dialog = (JDialog) container;
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
dialog.setModal(false);
dialog.setVisible(false);
dialog.dispose();

Runtime.getRuntime().exit(1);

以上所述将关闭进程并在处理JDialog容器后进行处理,还有一个好处是,如果此JDialog在任何其他JFrame或JDialog上运行,则父级不会终止,但如果此JDialog独立运行,则进程将完全终止,享受吧。


0

对我来说,只有在windowClosing事件中起作用:

dialog.addWindowListener(new WindowAdapter() 
                @Override
                public void windowClosing(WindowEvent e) {
                     System.exit(0);
                }
    });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接