Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 安全地打开和关闭模态JDialog(使用SwingWorker)_Java_Multithreading_Swing_Jdialog_Swingworker - Fatal编程技术网

Java 安全地打开和关闭模态JDialog(使用SwingWorker)

Java 安全地打开和关闭模态JDialog(使用SwingWorker),java,multithreading,swing,jdialog,swingworker,Java,Multithreading,Swing,Jdialog,Swingworker,我需要一种方法从数据库中获取一些数据,并防止用户在此时修改现有数据 我创建了一个SwingWorker来更新数据库,并创建了一个模态JDialog来向用户显示正在发生的事情(使用JProgressBar)。模态对话框的defaultCloseOperation设置为“不做任何事情”,因此只能通过正确的调用关闭它-我使用setVisible(false) SwingWorker在doInBackground()中执行一些操作,最后调用: myModalDialog.setVisible(false

我需要一种方法从数据库中获取一些数据,并防止用户在此时修改现有数据

我创建了一个SwingWorker来更新数据库,并创建了一个模态JDialog来向用户显示正在发生的事情(使用JProgressBar)。模态对话框的defaultCloseOperation设置为“不做任何事情”,因此只能通过正确的调用关闭它-我使用
setVisible(false)

SwingWorker在doInBackground()中执行一些操作,最后调用:

myModalDialog.setVisible(false);
我唯一关心的问题是: SwingWorker是否可能在工作人员繁殖后的行中执行
setVisible(false)
之前执行
setVisible(true)

如果是这样,
setVisible(true)
可能会永远阻塞(用户无法关闭模式窗口)

我是否必须实施以下措施:

while (!myModalDialog.isVisible()) {
    Thread.sleep(150);
}
myModalDialog.setVisible(false);
要确保它确实会关闭?

一般来说,是的

我要做的是在你的
doInBackground
方法中使用
SwingUtilities.invokeLater
来显示对话框,在你的
done
方法中隐藏对话框

这应该意味着,即使对话框没有进入屏幕,您也可以对流程获得更多的控制

小问题是你现在必须将对话框传递给工人,这样工人才能控制它

public class TestSwingWorkerDialog {

    public static void main(String[] args) {
        new TestSwingWorkerDialog();
    }
    private JDialog dialog;

    public TestSwingWorkerDialog() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                MyWorker worker = new MyWorker();
                worker.execute();

            }
        });
    }

    public class MyWorker extends SwingWorker<Object, Object> {

        @Override
        protected Object doInBackground() throws Exception {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    getDialog().setVisible(true);
                }
            });
            Thread.sleep(2000);

            return null;
        }

        @Override
        protected void done() {
            System.out.println("now in done...");
            JDialog dialog = getDialog();
            // Don't care, dismiss the dialog
            dialog.setVisible(false);
        }

    }

    protected JDialog getDialog() {
        if (dialog == null) {

            dialog = new JDialog();
            dialog.setModal(true);
            dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
            dialog.setLayout(new BorderLayout());
            dialog.add(new JLabel("Please wait..."));
            dialog.setSize(200, 200);
            dialog.setLocationRelativeTo(null);

        }

        return dialog;
    }

}
公共类TestSwingWorkerDialog{
公共静态void main(字符串[]args){
新的TestSwingWorkerDialog();
}
专用JDialog对话框;
公共测试SwingWorkerDialog(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}捕获(ClassNotFoundException ex){
}catch(实例化异常){
}捕获(非法访问例外){
}捕获(无支持的LookandFeelexception ex){
}
MyWorker=新的MyWorker();
worker.execute();
}
});
}
公共类MyWorker扩展SwingWorker{
@凌驾
受保护对象doInBackground()引发异常{
SwingUtilities.invokeLater(新的Runnable(){
@凌驾
公开募捐{
getDialog().setVisible(true);
}
});
《睡眠》(2000年);
返回null;
}
@凌驾
受保护的void done(){
System.out.println(“现在完成…”);
JDialog dialog=getDialog();
//别在意,取消对话
对话框.setVisible(false);
}
}
受保护的JDialog getDialog(){
如果(对话框==null){
dialog=newjdialog();
dialog.setModal(true);
setDefaultCloseOperation(JDialog.DO\u NOTHING\u ON\u CLOSE);
setLayout(新的BorderLayout());
添加(新的JLabel(“请稍候…”);
对话框。设置大小(200200);
对话框.setLocationRelativeTo(空);
}
返回对话框;
}
}

您应该调用
mymodaldiallog.setVisible(false)
done()
中,而不是
doInBackground()
。为什么不在执行之前调用
setVisible(true)
?setVisible(true)是一个阻塞调用哈哈-非常好的观点:-)为了更快地获得更好的帮助,发布一个。好的,我会再试一次。感谢您的done()技巧。SwingUtilities.invokeLater
EventQueue.invokeLater
之间有什么区别?如果我的问题很傻,很抱歉,但在您的示例中,可以保证invokeLater的run方法一定会在工作完成之前运行()?在我看来,我这篇文章的主要问题仍然存在——理论上不确定的并发性,但我可能是错的。@M.M.没有。SwingUtilities.invokeLater将调用转发给EventQueue.invokeLater@user1713059这样做的目的是保证1。该对话框将仅在工作程序启动和2之后打开。在工作完成之前不会关闭(或试图关闭)。因为done方法是在EDT的上下文中执行的,使用了与我打开它类似的方法,所以open事件将在关闭之前执行,因为它首先被添加到队列中。@我在这里得到了一个关于这一点的精度:
public class TestSwingWorkerDialog {

    public static void main(String[] args) {
        new TestSwingWorkerDialog();
    }
    private JDialog dialog;

    public TestSwingWorkerDialog() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException ex) {
                } catch (InstantiationException ex) {
                } catch (IllegalAccessException ex) {
                } catch (UnsupportedLookAndFeelException ex) {
                }

                MyWorker worker = new MyWorker();
                worker.execute();

            }
        });
    }

    public class MyWorker extends SwingWorker<Object, Object> {

        @Override
        protected Object doInBackground() throws Exception {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    getDialog().setVisible(true);
                }
            });
            Thread.sleep(2000);

            return null;
        }

        @Override
        protected void done() {
            System.out.println("now in done...");
            JDialog dialog = getDialog();
            // Don't care, dismiss the dialog
            dialog.setVisible(false);
        }

    }

    protected JDialog getDialog() {
        if (dialog == null) {

            dialog = new JDialog();
            dialog.setModal(true);
            dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
            dialog.setLayout(new BorderLayout());
            dialog.add(new JLabel("Please wait..."));
            dialog.setSize(200, 200);
            dialog.setLocationRelativeTo(null);

        }

        return dialog;
    }

}