等待jdialog关闭

发布于 2024-12-11 16:36:15 字数 882 浏览 0 评论 0原文

我有一个类 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 但这没有帮助。

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

    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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

本王不退位尔等都是臣 2024-12-18 16:36:15

同样,关键是对话框是否为模态

如果它是模态的,则不需要 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);
   }
}

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:

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 sscce for us to analyze, run, and modify.

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

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);
   }
}
梨涡少年 2024-12-18 16:36:15

WindowListener.windowClosed()

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

对于 JDialog.setDefaultCloseOperation()

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

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

该值默认设置为 HIDE_ON_CLOSE。

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

Javadoc for WindowListener.windowClosed():

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

And for 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 dispose the dialog after invoking any registered WindowListener objects

The value is set to HIDE_ON_CLOSE by default.

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

随波逐流 2024-12-18 16:36:15

回答您的问题

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

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

仅使用 WindowListener 创建一个 JDialog (JDialog.DO_NOTHING_ON_CLOSE),并将其重新用于另一个 Action,最终操作将始终为 < code>setVisible(false),如果您的代码成功结束,则从 JDialog 中删除子级,您的 JDialog 已准备好进行另一项工作

answer to your question

add WindowListener to your JDialog (JDialog.DO_NOTHING_ON_CLOSE) , on windowClosing event to try to run your code, if ends with success then call dispose(), or 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 JDialog is prepared for another job

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文