与 Swingworker 的对话是先有鸡还是先有蛋

2024-03-20

我试图遵循 Java 最佳实践,不在主线程(EDT)上执行长时间任务。所以我计划使用带有模态对话框的 swingWorker。这样,模式对话框会阻止用户执行任何操作,直到该任务完成,并且我可以在该过程发生时更新对话框上的状态。

现在的问题是,对于模态对话框,它不仅会阻止用户,而且在调用 setVisible 后什么也不会发生

所以如果我这样做

dialog.setVisible(true);
new SwingWorkerTask().execute(); //This does not get called

如果我这样做

new SwingWorkerTask().execute();
dialog.setVisible(true); // Well what the point of setting visible after the fact.

那么如何在任务发生时阻止用户操作并显示对话框?

谢谢


如果你这样做的话,那就只是先有鸡还是先有蛋。您可以在 EDT 上构造所有 Swing 对象,然后让您的SwingWorker(或任何其他线程)通过指示 EDT 执行更新来管理所有更新SwingUtilities.invokeLater(Runnable) https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html#invokeLater%28java.lang.Runnable%29.

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class RudeProgressBar extends JFrame {

    private JButton button;

    public RudeProgressBar() {
        setTitle("Rude Progress Bar");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        button = new JButton("Do teh work");
        add(button, BorderLayout.SOUTH);

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JDialog dialog = new JDialog(RudeProgressBar.this, true);
                dialog.setTitle("Doing teh work");
                dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
                final JProgressBar progressBar = new JProgressBar(0, 100);
                dialog.setLayout(new BorderLayout());
                dialog.add(progressBar);
                dialog.setSize(100, 100);
                dialog.setLocationRelativeTo(RudeProgressBar.this);
                MyTask task = new MyTask(dialog);
                task.addPropertyChangeListener(new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        if ("progress".equals(evt.getPropertyName())) {
                            progressBar.setValue((Integer)evt.getNewValue());
                        }
                    }
                });
                task.execute();
            }
        });

        setSize(200, 200);
        setLocationRelativeTo(null);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new RudeProgressBar().setVisible(true);
            }
        });
    }

    private class MyTask extends SwingWorker<Void, Void> {

        private final JDialog dialog;

        public MyTask(JDialog dialog) {
            this.dialog = dialog;
        }

        @Override
        protected Void doInBackground() throws Exception {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    dialog.setVisible(true);
                }
            });

            int progress = 0;
            for (int i = 0; i < 5; i++) {
                Thread.sleep(1000);
                setProgress(progress += 20);
            }            

            return null;
        }

        @Override
        protected void done() {
            dialog.setVisible(false);
            dialog.dispose();
        }
    }
}

如果您担心invokeLater实施(内部SwingWorker.doInBackground) 可能会在之后执行SwingWorker.done,只需将代码放入done进入另一个invokeLater。通过这样做,您可以将您的RunnableEDT 的实现以特定顺序执行它们。即使从 EDT 本身调用此方法,也会发生排队。

请注意,如果您看一下SwingWorker实现,你会发现它依赖于javax.swing.Timer https://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html执行done()Timer本身调用invokeLater,所以在里面调用它done再次等于什么也不做。不过,如果你这样做的话,不会有什么问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

与 Swingworker 的对话是先有鸡还是先有蛋 的相关文章

随机推荐

  • minikube:无法连接本地部署的 nginx 服务

    我已经在我的 ubuntu 16 04 机器上安装了 minikube 并启动了一个集群 并显示一条消息 Kubernetes is available at https 192 168 99 100 443 接下来 我使用以下命令部署了
  • 如何使用 spacy 或 nltk 检索句子的主要意图?

    我有一个用例 我想使用 spacy 或 nltk 或任何 NLP 库提取句子的主要有意义部分 例句1 我怎样才能发出反对骚扰的声音 意图是 大声疾呼反对骚扰 例句2 唐老鸭是由哪个漫画家 哪个人 谁创作的 意图是 唐老鸭是由 创造的 例句3
  • 使用实体框架记录每个数据更改

    客户需要将每个数据更改与进行修改的实际用户一起记录到日志表中 该应用程序使用一个 SQL 用户来访问数据库 但我们需要记录 真实 用户 ID 我们可以在 t sql 中通过为每个表插入和更新编写触发器并使用 context info 来存储
  • 从 C++ 中的给定文件点读取目录

    我有两个程序将同时读取 写入文件到同一目录 但不会同时读取 写入文件 我已经完成了写作部分 但我正在努力获得阅读目录部分的一半体面且有效的实现 目录中的文件遵循以下命名方案 Image INDEX KEY DEL TIMESTAMP IND
  • Azure Function CosmosDBTrigger 不可扩展

    我有一个带有 CosmosDBTrigger 的 Azure 函数 用于使用 Application Insights 监控的消费游戏 正在监控的集合有500 000插入更改提要中 消费计划将实例数量扩大到15几分钟之内 但只有第一个实例能
  • 使用 axios 递归获取数据并链接结果

    我有一个模式的网址http www data com 1 其中末尾的 1 可以一直运行到一个未预定义的数字 它返回一个数组 我需要将我得到的所有数组连接成一个 我的策略是递归执行 get 请求 直到收到 404 错误 然后返回结果 var
  • Kubernetes 上的 Spring Boot 应用程序 如何使用外部 message.properties 文件来支持 i18n 和 l10n?

    我们有一个部署到 Kubernetes 的 Spring Boot 应用程序 我们正在向此应用程序添加 i18n 功能 并希望将 messages properties 文件放置在应用程序 jar war 之外 我已经能够在春季启动中做到这
  • PowerShell 代码整洁还是重新格式化? [复制]

    这个问题在这里已经有答案了 可能的重复 有 PowerShell 代码格式化程序 漂亮的打印机吗 https stackoverflow com questions 2987176 is there a powershell code fo
  • 如何在数据框中按名称删除列

    我有一个很大的数据集 我想阅读特定的列或删除所有其他列 data lt read dta file dta 我选择我不感兴趣的列 var out lt names data names data in c iden name x serv
  • 反向填充猫鼬

    我怎样才能反向填充 mongo 我有 2 个模式 User var user scheme new mongoose Schema name String age Number roles type mongoose Schema Type
  • GNU less 的 bash 循环每 2 分钟刷新一次

    我有一台 Linux 机器 其中有一个数据文件夹和一个脚本 该脚本会生成一个报告 xlsx 电子表格文件 显示正在运行的文件夹中不断变化的内容 我使用 xlsx2tsv 脚本将其转换为 tsv 文本 耗时不到一秒 该脚本大约需要 1 分钟来
  • 使用 Typescript 和 React 三纤维的着色器

    我正在尝试将着色器与 React 三纤维和 Typescript 一起使用 着色器文件 import ShaderMaterial from three import extend from react three fiber class
  • 在类组件的方法中获取查询

    Apollo 客户端 2 6 3 与反应 是否可以在类组件的方法中获取数据 我正在构建一个全局搜索组件 并且我只想在键入第三个 以及每个后续 字符时才获取 数据 现在它是用 fetch api 实现的 但我想切换到 apollo 客户端和
  • 如何使用 gitignore 忽略非点文件(所有非隐藏目录,在我的存储库的根目录中)?

    我想跟踪我的 点文件 我想要 gitignore 来忽略所有隐藏文件 文件扩展名 本质上与以下相反 Git 如何忽略隐藏目录 https stackoverflow com questions 8021441 git how to igno
  • 如何使特定单词在文本中易于理解其含义?

    我正在为 iPhone 开发一本散文书 所以我将所有诗歌和文本存储在核心数据中 一个名为story以及名为的属性details其中包含整个轶事 但问题就在这里 如果用户想要触摸特定的单词和诗歌来了解它们的含义和定义 我应该如何处理这个任务
  • 销毁 Backbone 集合中每个模型的最简洁方法?

    第一次尝试时我写了 this collection each function element element destroy 这不起作用 因为它类似于ConcurrentModificationException在 Java 中 所有其他
  • java 1.7 中的无效标志参数

    我的任务是使用 Java 7 创建 spring boot 应用程序 因此 像往常一样 我在 start spring io 资源上创建了一个模板 并通过以下方式打开他File gt New gt Project from Existing
  • 未定义的预处理器变量“$(var.WixInstall.TargetPath)”。 WixInstaller D:work\Extractor\WixInstaller\Product.wxs

    我在使用 wix 创建 Windows 安装程序时遇到以下错误 未定义的预处理器变量 var WixInstall TargetPath WixInstaller D work Extractor WixInstaller Product
  • 在mongo中执行优先级查询

    样本文件 name John age 35 address join month 3 的员工优先级为 1 地址包含字符串 Avenue 的员工优先级为 2 地址包含字符串 Street 的员工优先级为 3 地址包含字符串 Road 的员工优
  • 与 Swingworker 的对话是先有鸡还是先有蛋

    我试图遵循 Java 最佳实践 不在主线程 EDT 上执行长时间任务 所以我计划使用带有模态对话框的 swingWorker 这样 模式对话框会阻止用户执行任何操作 直到该任务完成 并且我可以在该过程发生时更新对话框上的状态 现在的问题是