Java 如果事件分派线程未暂停,模态对话框如何等待?

Java 如果事件分派线程未暂停,模态对话框如何等待?,java,multithreading,swing,modal-dialog,Java,Multithreading,Swing,Modal Dialog,在下面的示例中,模式对话框在事件调度线程内打开。由于对话框是模态的,所以方法setVisible()在关闭之前不会返回 有人可能怀疑这是导致事件调度线程暂停的原因,但这是错误的,因为按钮正在运行 因此,setVisible()方法没有阻塞线程 问题是:是否可以在不阻塞过程的情况下显示模态对话框 package tests.javax.swing; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import jav

在下面的示例中,模式对话框在事件调度线程内打开。由于对话框是模态的,所以方法
setVisible()
在关闭之前不会返回

有人可能怀疑这是导致事件调度线程暂停的原因,但这是错误的,因为按钮正在运行

因此,
setVisible()
方法没有阻塞线程

问题是:是否可以在不阻塞过程的情况下显示模态对话框

package tests.javax.swing;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Try_JDialog_Modality2 {

    private static final Logger log = LoggerFactory.getLogger(Try_JDialog_Modality2.class);

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                AbstractAction popupAction = new AbstractAction("popup") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(null, "popup");
                    }

                };

                JDialog dialog = new JDialog((JFrame)null, true);
                dialog.setLayout(new FlowLayout());
                dialog.add(new JButton(popupAction));

                dialog.pack();
                dialog.setLocationRelativeTo(null);

                dialog.setVisible(true);

                log.debug("After set visible");



            }
        });


    }

}
更新

我可以对以下代码段执行相同的操作:

//dialog.setVisible(true);
            new Thread(new Runnable() {

                @Override
                public void run() {
                    dialog.setVisible(true);
                }
            }).start();

            log.debug("After set visible");
还有较短的路吗?

你的问题:

问题是:是否可以在不阻塞过程的情况下显示模态对话框

package tests.javax.swing;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Try_JDialog_Modality2 {

    private static final Logger log = LoggerFactory.getLogger(Try_JDialog_Modality2.class);

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                AbstractAction popupAction = new AbstractAction("popup") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(null, "popup");
                    }

                };

                JDialog dialog = new JDialog((JFrame)null, true);
                dialog.setLayout(new FlowLayout());
                dialog.add(new JButton(popupAction));

                dialog.pack();
                dialog.setLocationRelativeTo(null);

                dialog.setVisible(true);

                log.debug("After set visible");



            }
        });


    }

}
是,在显示模式对话框之前调用方法。对于某些事情,最好使用回调类型的设置来完成,例如使用PropertyChangeListener或其他类型的侦听器。如果在可视化模式对话框之前设置并调用了它,那么它应该可以工作

至于问题的如何部分,我相信它会阻止其他窗口的输入,但不会停止Swing事件线程。它确实会停止调用代码的程序流,可能是通过调用
SwingUtilities.invokeAndWait(…)
。最适合您查看Swing源代码以了解详细信息


编辑 关于您的更新,永远不要执行以下操作:

new Thread(new Runnable() {

    @Override
    public void run() {
        dialog.setVisible(true);
    }
}).start();
因为您现在保证启动Swing事件线程的对话框关闭

你的问题:

问题是:是否可以在不阻塞过程的情况下显示模态对话框

package tests.javax.swing;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Try_JDialog_Modality2 {

    private static final Logger log = LoggerFactory.getLogger(Try_JDialog_Modality2.class);

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                AbstractAction popupAction = new AbstractAction("popup") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(null, "popup");
                    }

                };

                JDialog dialog = new JDialog((JFrame)null, true);
                dialog.setLayout(new FlowLayout());
                dialog.add(new JButton(popupAction));

                dialog.pack();
                dialog.setLocationRelativeTo(null);

                dialog.setVisible(true);

                log.debug("After set visible");



            }
        });


    }

}
是,在显示模式对话框之前调用方法。对于某些事情,最好使用回调类型的设置来完成,例如使用PropertyChangeListener或其他类型的侦听器。如果在可视化模式对话框之前设置并调用了它,那么它应该可以工作

至于问题的如何部分,我相信它会阻止其他窗口的输入,但不会停止Swing事件线程。它确实会停止调用代码的程序流,可能是通过调用
SwingUtilities.invokeAndWait(…)
。最适合您查看Swing源代码以了解详细信息


编辑 关于您的更新,永远不要执行以下操作:

new Thread(new Runnable() {

    @Override
    public void run() {
        dialog.setVisible(true);
    }
}).start();
因为您现在保证启动Swing事件线程的对话框关闭

你的问题:

问题是:是否可以在不阻塞过程的情况下显示模态对话框

package tests.javax.swing;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Try_JDialog_Modality2 {

    private static final Logger log = LoggerFactory.getLogger(Try_JDialog_Modality2.class);

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                AbstractAction popupAction = new AbstractAction("popup") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(null, "popup");
                    }

                };

                JDialog dialog = new JDialog((JFrame)null, true);
                dialog.setLayout(new FlowLayout());
                dialog.add(new JButton(popupAction));

                dialog.pack();
                dialog.setLocationRelativeTo(null);

                dialog.setVisible(true);

                log.debug("After set visible");



            }
        });


    }

}
是,在显示模式对话框之前调用方法。对于某些事情,最好使用回调类型的设置来完成,例如使用PropertyChangeListener或其他类型的侦听器。如果在可视化模式对话框之前设置并调用了它,那么它应该可以工作

至于问题的如何部分,我相信它会阻止其他窗口的输入,但不会停止Swing事件线程。它确实会停止调用代码的程序流,可能是通过调用
SwingUtilities.invokeAndWait(…)
。最适合您查看Swing源代码以了解详细信息


编辑 关于您的更新,永远不要执行以下操作:

new Thread(new Runnable() {

    @Override
    public void run() {
        dialog.setVisible(true);
    }
}).start();
因为您现在保证启动Swing事件线程的对话框关闭

你的问题:

问题是:是否可以在不阻塞过程的情况下显示模态对话框

package tests.javax.swing;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Try_JDialog_Modality2 {

    private static final Logger log = LoggerFactory.getLogger(Try_JDialog_Modality2.class);

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                AbstractAction popupAction = new AbstractAction("popup") {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        JOptionPane.showMessageDialog(null, "popup");
                    }

                };

                JDialog dialog = new JDialog((JFrame)null, true);
                dialog.setLayout(new FlowLayout());
                dialog.add(new JButton(popupAction));

                dialog.pack();
                dialog.setLocationRelativeTo(null);

                dialog.setVisible(true);

                log.debug("After set visible");



            }
        });


    }

}
是,在显示模式对话框之前调用方法。对于某些事情,最好使用回调类型的设置来完成,例如使用PropertyChangeListener或其他类型的侦听器。如果在可视化模式对话框之前设置并调用了它,那么它应该可以工作

至于问题的如何部分,我相信它会阻止其他窗口的输入,但不会停止Swing事件线程。它确实会停止调用代码的程序流,可能是通过调用
SwingUtilities.invokeAndWait(…)
。最适合您查看Swing源代码以了解详细信息


编辑 关于您的更新,永远不要执行以下操作:

new Thread(new Runnable() {

    @Override
    public void run() {
        dialog.setVisible(true);
    }
}).start();
因为您现在保证启动Swing事件线程的对话框关闭

对话框。设置可见(true)应在AWT调度程序线程上运行。所以你应该换一种方式来做

public buttonPressed_OpenDialog_and_doTask(){
    new Thread(new Runnable() {
        @Override
        public void run() {
            /* my worker background task */
            dialog.dispose(); // at the end of task call this
        }
        }).start();
    dialog.setVisible(true);
    // we will continue when worker thread finishes
}
请注意,即使在AWT事件调度程序线程上阻塞(通过setVisible()方法)。AWT事件调度器线程仍在运行,因此所有AWT通知都像往常一样工作。看

请注意,即使后台任务太快,并且在前面的线程中调用
dialog.dispose()
之前调用
dialog.setVisible(true)
,所有这些都是正常的。幸运的是,
dialog.dispose()
礼貌地等待对话框出现

对话框。设置可见(true)应在AWT调度程序线程上运行。所以你应该换一种方式来做

public buttonPressed_OpenDialog_and_doTask(){
    new Thread(new Runnable() {
        @Override
        public void run() {
            /* my worker background task */
            dialog.dispose(); // at the end of task call this
        }
        }).start();
    dialog.setVisible(true);
    // we will continue when worker thread finishes
}
请注意,即使在AWT事件调度程序线程上阻塞(通过setVisible()方法)。AWT事件调度器线程仍在运行,因此所有AWT通知都像往常一样工作。看

请注意,即使后台任务太快,并且在前面的线程中调用
dialog.dispose()
之前调用
dialog.setVisible(true)
,所有这些都是正常的。幸运的是,
dialog.dispose()
礼貌地等待对话框出现

对话框。设置可见(true)应在AWT调度程序线程上运行。所以你应该换一种方式来做

public buttonPressed_OpenDialog_and_doTask(){
    new Thread(new Runnable() {
        @Override
        public void run() {
            /* my worker background task */
            dialog.dispose(); // at the end of task call this
        }
        }).start();
    dialog.setVisible(true);
    // we will continue when worker thread finishes
}
请注意,即使在AWT事件调度程序线程上阻塞(通过setVisible()方法)。AWT事件调度程序线程仍在运行