java 等待 jdialog 关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7855227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:41:44  来源:igfitidea点击:

wait for jdialog to close

javaswingjdialog

提问by ed1t

I have a class FilePathDialog which extends JDialog and that class is being called from some class X. Here is a method in class X

我有一个类 FilePathDialog,它扩展了 JDialog 并且正在从某个类 X 调用该类。这是 X 类中的一个方法

    projectDialog = new FilePathDialog();   
    projectDialog.setVisible(true);

    projectDialog.addWindowListener(new WindowAdapter() {            
        public void windowClosing(WindowEvent e) {
            System.out.println("Window closing");
            try {
                doWork();
            } catch (Throwable t) {
                t.printStackTrace();
            }                
        }

        public void windowClosed(WindowEvent e) {
            System.out.println("Window closed");
            try {
                doWork();
            } catch (Throwable t) {
                t.printStackTrace();
            }                
        }
    });     

doWork never gets called when the JDialog window closes. All I'm trying to do is wait for the JDialog to close before it proceeds in the method. I also tried using SwingWorker and Runnable but that did not help.

当 JDialog 窗口关闭时,doWork 永远不会被调用。我要做的就是等待 JDialog 关闭,然后再继续执行该方法。我也尝试使用 SwingWorker 和 Runnable 但这没有帮助。

回答by Hovercraft Full Of Eels

Again, the key is is the dialog modal or not?

同样,关键是对话框模式与否

If it's modal, then there's no need for a WindowListener as you will know that the dialog has been dealt with since code will resume immediately below your call to setVisible(true)on the dialog. i.e., this should work:

如果它是模态的,则不需要 WindowListener,因为您将知道该对话框已被处理,因为代码将在您setVisible(true)对对话框的调用下方立即恢复。即,这应该有效:

projectDialog = new FilePathDialog();   
projectDialog.setVisible(true);
doWork(); // will not be called until the dialog is no longer visible

If on the other hand it's mode-less, then a WindowListener should work, and you've likely got another problem in code not shown here, and you'll want to post an ssccefor us to analyze, run, and modify.

另一方面,如果它是无模式的,那么 WindowListener 应该可以工作,并且您可能在此处未显示的代码中遇到了另一个问题,您需要发布一个sscce供我们分析、运行和修改。

Edit for gpeche
Please check out this SSCCE that shows that the 3 types of default closing parameters will trigger the window listener:

为 gpeche 编辑
请查看此 SSCCE,其中显示了 3 种类型的默认关闭参数将触发窗口侦听器:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DialogClosing {
   private static void createAndShowGui() {
      JFrame frame = new JFrame("DialogClosing");

      JPanel mainPanel = new JPanel();
      mainPanel.add(new JButton(new MyAction(frame, JDialog.DISPOSE_ON_CLOSE, "DISPOSE_ON_CLOSE")));
      mainPanel.add(new JButton(new MyAction(frame, JDialog.HIDE_ON_CLOSE, "HIDE_ON_CLOSE")));
      mainPanel.add(new JButton(new MyAction(frame, JDialog.DO_NOTHING_ON_CLOSE, "DO_NOTHING_ON_CLOSE")));

      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class MyAction extends AbstractAction {
   private JDialog dialog;
   private String title;

   public MyAction(JFrame frame, int defaultCloseOp, final String title) {
      super(title);
      dialog = new JDialog(frame, title, false);
      dialog.setDefaultCloseOperation(defaultCloseOp);
      dialog.setPreferredSize(new Dimension(300, 200));
      dialog.pack();
      dialog.addWindowListener(new WindowAdapter() {
         @Override
         public void windowClosed(WindowEvent e) {
            System.out.println(title + " window closed");
         }
         @Override
         public void windowClosing(WindowEvent e) {
            System.out.println(title + " window closing");
         }
      });

      this.title = title;
   }

   @Override
   public void actionPerformed(ActionEvent arg0) {
      dialog.setVisible(true);
   }
}

回答by gpeche

Javadoc for WindowListener.windowClosed():

Javadoc 用于WindowListener.windowClosed()

Invoked when a window has been closed as the result of calling disposeon the window.

由于在窗口上调用dispose导致窗口关闭时调用。

And for JDialog.setDefaultCloseOperation():

而对于JDialog.setDefaultCloseOperation()

Sets the operation which will happen by default when the user initiates a "close" on this dialog. The possible choices are:

设置当用户在此对话框上启动“关闭”时默认发生的操作。可能的选择是:

  • DO_NOTHING_ON_CLOSE - do not do anything - require the program to handle the operation in the windowClosing method of a registered WindowListener object.
  • HIDE_ON_CLOSE - automatically hide the dialog after invoking any registered WindowListener objects
  • DISPOSE_ON_CLOSE - automatically hide and disposethe dialog after invoking any registered WindowListener objects
  • DO_NOTHING_ON_CLOSE - 不做任何事情 - 要求程序处理已注册 WindowListener 对象的 windowClosing 方法中的操作。
  • HIDE_ON_CLOSE - 在调用任何注册的 WindowListener 对象后自动隐藏对话框
  • DISPOSE_ON_CLOSE -在调用任何注册的 WindowListener 对象后自动隐藏和处理对话框

The value is set to HIDE_ON_CLOSE by default.

默认情况下,该值设置为 HIDE_ON_CLOSE。

That suggests that you should call projectDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);after instantiating FilePathDialog.

这表明您应该projectDialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);在实例化之后调用FilePathDialog

回答by mKorbel

answer to your question

回答你的问题

add WindowListenerto your JDialog(JDialog.DO_NOTHING_ON_CLOSE) , on windowClosingevent to try to run your code, if ends with success then call dispose(), or setVisible(false)

WindowListener添加 到您的JDialog( JDialog.DO_NOTHING_ON_CLOSE),在windowClosing事件上尝试运行您的代码,如果以成功结束则调用dispose(),或setVisible(false)

I don't agreed with your idea, another workaround

我不同意你的想法,另一种解决方法

create only one JDialog (JDialog.DO_NOTHING_ON_CLOSE)with WindowListener, and re-use that for another Action, final action will be always setVisible(false), if your code ends with success, then remove the child(s) from JDialog, your JDialogis prepared for another job

只创建一个JDialog (JDialog.DO_NOTHING_ON_CLOSE)具有WindowListener和再利用,对于另一个Action,最后的行动将永远setVisible(false),如果成功代码结束,然后取出孩子(一个或多个)JDialog,你JDialog是为另一份工作准备