等待jdialog关闭

时间:2011-10-21 20:59:33

标签: java swing jdialog

我有一个类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();
            }                
        }
    });     
当JDialog窗口关闭时,

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

3 个答案:

答案 0 :(得分:17)

同样,关键是 是对话模式还是

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

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

如果另一方面它是无模式的,那么一个WindowListener应该可以工作,你可能在这里没有显示的代码中遇到另一个问题,你要发布sscce给我们分析,运行和修改。

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

答案 1 :(得分:3)

WindowListener.windowClosed()的Javadoc:

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

对于JDialog.setDefaultCloseOperation()

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

  • DO_NOTHING_ON_CLOSE - 不执行任何操作 - 要求程序在已注册的WindowListener对象的windowClosing方法中处理操作。
  • HIDE_ON_CLOSE - 在调用任何已注册的WindowListener对象后自动隐藏对话框
  • DISPOSE_ON_CLOSE - 在调用任何已注册的WindowListener对象后自动隐藏和处理对话框

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

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

答案 2 :(得分:2)

回答你的问题

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

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

只使用JDialog (JDialog.DO_NOTHING_ON_CLOSE)创建一个WindowListener,并将其重新用于另一个Action,如果您的代码成功结束,则最终操作将始终为setVisible(false),然后从JDialog移除子项,您的JDialog已准备好接受其他工作