简体   繁体   English

如果事件分配线程没有暂停,模态对话框如何等待?

[英]How can modal dialog wait, if event dispatching thread is not paused?

In an example below, the modal dialog is opened inside event dispatching thread. 在下面的示例中,将在事件分配线程内部打开模式对话框。 Since dialog is modal, method setVisible() is not return until it is closed. 由于对话框是模式对话框,因此直到关闭方法setVisible()才返回。

One may suspect this is causing event dispatching thread paused, but it is wrong, since button is operating. 可能有人怀疑这会导致事件调度线程暂停,但这是错误的,因为按钮正在运行。

Hence, setVisible() method is not blocking the thread. 因此, setVisible()方法不会阻塞线程。

The question is: is it possible to show modal dialog without blocking a procedure? 问题是:是否可以显示模式对话框而不阻塞程序?

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");



            }
        });


    }

}

UPDATE 更新

I can do the same with the following snippet: 我可以使用以下代码段执行相同的操作:

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

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

            log.debug("After set visible");

Is there a shorter way? 有没有更短的方法?

Your question: 你的问题:

The question is: is it possible to show modal dialog without blocking a procedure? 问题是:是否可以显示模式对话框而不阻塞程序?

Yes, call the method before displaying the modal dialog. 是的, 显示模式对话框之前调用该方法。 For certain things this might be best accomplished using a call-back type of set up, such as by using a PropertyChangeListener or other type of listener. 对于某些事情,最好使用回调类型的设置(例如,使用PropertyChangeListener或其他类型的侦听器)来实现。 If it is set up and called prior to visualizing the modal dialog, it should work. 如果在可视化模态对话框之前进行了设置和调用,它应该可以工作。

As to the how portion of your question, I believe that it blocks input to the other windows but does not stop the Swing event thread. 至于你的问题是如何部分,我认为,其输入块到其他窗口,但不会停止挥棒事件线程。 It does stop program flow from the calling code though, perhaps via a call to SwingUtilities.invokeAndWait(...) . 但是,它确实可以通过调用SwingUtilities.invokeAndWait(...)来停止程序从调用代码流。 Best for you to peek at the Swing source code for the details. 最适合您查看Swing源代码以获取详细信息。


Edit Regarding your update, never do this: 编辑关于您的更新, 永远不要这样做:

new Thread(new Runnable() {

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

as you are now guaranteeing to start the dialog off of the Swing event thread. 因为你现在保证启动对话框关闭 Swing事件线程。

dialog.setVisible(true); shall be run on AWT Dispatcher thread. 应在AWT Dispatcher线程上运行。 So you shall do it other way around. 因此,您应该选择其他方式。

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
}

Note that even when you block on AWT event dispatcher thread (by method setVisible()). 请注意,即使您在AWT事件调度程序线程上阻塞(通过setVisible()方法)。 The AWT event dispatcher thread is still running somehow - so all AWT notifications are working like usual. AWT事件调度程序线程仍以某种方式运行-因此所有AWT通知都像往常一样工作。 See doc dialog.setVisible() 请参阅doc dialog.setVisible()

Note that all is ok even in case that background task would be to fast and it would call dialog.dispose() before dialog.setVisible(true) is called in previous thread. 请注意,即使后台任务要快并且在上一个线程中调用dialog.setVisible(true)之前会调用dialog.dispose() ,也可以。 Luckily dialog.dispose() politely waits till dialog gets visible. 幸运的是, dialog.dispose()礼貌地等到对话框可见。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM