批处理文件运行时显示不确定的 JProgressBar

2023-12-22

我已经浏览 SO 和谷歌一段时间来寻找这个问题的答案,但我似乎找不到真正有效的答案。我将从头开始:

我创建了一个 Java 类,其方法在后台运行批处理文件(不出现命令窗口)。该程序运行良好,但最终用户会有点困惑,因为批处理文件需要一段时间才能完成 - 用户不知道程序是否仍在运行。批处理脚本执行完毕后,会出现一个消息对话框,表示已完成,但在该方法运行和该对话框出现之间的一段时间内,程序看起来好像什么也没做。

所以这是我的问题:我非常想显示一个带有文本区域的新框架,该文本区域显示批处理文件的输出。但是,我知道如果不创建临时文件、写入临时文件、读取临时文件等,这是非常困难的。如果可能的话,我宁愿避免这种情况。因此,我决定最好在进程运行时显示不确定的 JProgressBar,并在进程完成时关闭它。不幸的是,我认为 Swing 无法处理这个问题,因为它需要同时运行多个进程。我听说过 SwingWorker,但不太确定在这种情况下如何使用它。我有以下 SSCCE,它可以工作,但没有实现进度条。

public myClass(){
    public static void main(String[] args){
        String[] commands = {"cmd.exe", "/C", "C:\\users\\....\\myBat.bat"};
        Process p = Runtime.getRuntime().exec(commands);
        p.waitFor()
        JOptionPane.showMessageDialog(null, "Process finished!");
    }
}

当 p.waitFor() 等待进程时,屏幕上没有任何内容。我只想向用户显示进程仍在运行。想法?谢谢!


你可以运行一个ProcessBuilder在一个背景下SwingWorker https://docs.oracle.com/javase/tutorial/uiswing/concurrency/interim.html,如下图所示,得到both输出和进度条。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.swing.*;

/**
 * @se http://stackoverflow.com/a/20603012/230513
 * @see http://stackoverflow.com/a/17763395/230513
 */
public class SwingWorkerExample {

    private final JLabel statusLabel = new JLabel("Status: ", JLabel.CENTER);
    private final JTextArea textArea = new JTextArea(20, 20);
    private JButton startButton = new JButton("Start");
    private JButton stopButton = new JButton("Stop");
    private JProgressBar bar = new JProgressBar();
    private BackgroundTask backgroundTask;
    private final ActionListener buttonActions = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            JButton source = (JButton) ae.getSource();
            if (source == startButton) {
                textArea.setText(null);
                startButton.setEnabled(false);
                stopButton.setEnabled(true);
                backgroundTask = new BackgroundTask();
                backgroundTask.execute();
                bar.setIndeterminate(true);
            } else if (source == stopButton) {
                backgroundTask.cancel(true);
                backgroundTask.done();
            }
        }
    };

    private void displayGUI() {
        JFrame frame = new JFrame("Swing Worker Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setBorder(
            BorderFactory.createEmptyBorder(5, 5, 5, 5));
        panel.setLayout(new BorderLayout(5, 5));

        JScrollPane sp = new JScrollPane();
        sp.setBorder(BorderFactory.createTitledBorder("Output: "));
        sp.setViewportView(textArea);

        startButton.addActionListener(buttonActions);
        stopButton.setEnabled(false);
        stopButton.addActionListener(buttonActions);
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(startButton);
        buttonPanel.add(stopButton);
        buttonPanel.add(bar);

        panel.add(statusLabel, BorderLayout.PAGE_START);
        panel.add(sp, BorderLayout.CENTER);
        panel.add(buttonPanel, BorderLayout.PAGE_END);

        frame.setContentPane(panel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private class BackgroundTask extends SwingWorker<Integer, String> {

        private int status;

        public BackgroundTask() {
            statusLabel.setText((this.getState()).toString());
        }

        @Override
        protected Integer doInBackground() {
            try {
                ProcessBuilder pb = new ProcessBuilder("ls", "-lR", "/");
                pb.redirectErrorStream(true);
                Process p = pb.start();
                String s;
                BufferedReader stdout = new BufferedReader(
                    new InputStreamReader(p.getInputStream()));
                while ((s = stdout.readLine()) != null && !isCancelled()) {
                    publish(s);
                }
                if (!isCancelled()) {
                    status = p.waitFor();
                }
                p.getInputStream().close();
                p.getOutputStream().close();
                p.getErrorStream().close();
                p.destroy();
            } catch (IOException | InterruptedException ex) {
                ex.printStackTrace(System.err);
            }
            return status;
        }

        @Override
        protected void process(java.util.List<String> messages) {
            statusLabel.setText((this.getState()).toString());
            for (String message : messages) {
                textArea.append(message + "\n");
            }
        }

        @Override
        protected void done() {
            statusLabel.setText((this.getState()).toString() + " " + status);
            stopButton.setEnabled(false);
            startButton.setEnabled(true);
            bar.setIndeterminate(false);
        }

    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new SwingWorkerExample().displayGUI();
            }
        });
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

批处理文件运行时显示不确定的 JProgressBar 的相关文章

随机推荐

  • 如何求整数n次根?

    我想找到小于或等于n的k次方根的最大整数 我试过 int n 1 k 但对于 n 125 k 3 这给出了错误的答案 我碰巧知道 5 的立方是 125 gt gt gt int 125 1 3 4 有什么更好的算法 背景 2011 年 这个
  • 随机选择一个目录下的100个文档

    该目录下大约有2000个文档 我想随机选择一些文档并自动将它们复制到新目录 一些相关信息 https stackoverflow com questions 701402 best way to choose a random file f
  • ASP.NET core Web API授权属性返回404错误并强制重定向

    我有 asp net core 2 0 解决方案 其中包含以下项目 Data EF代码的类库 OAuth 作为 IdentityServer4 代码的 Web 应用程序项目 Api 用于我创建为空 Web 项目的 API 现在OAuth项目
  • 如何映射具有未知嵌套级别的数组?

    我有一个可以有答案的注释数组 因此数组的每个元素 注释 都可以有嵌套元素 注释 并且嵌套级别未知 但我需要在 ReactJs 中渲染这个数组 以使用给定的值显示这些注释嵌套级别 comment 1 comment 2 comment 3 c
  • 如何仅当上一步失败时才在 Jenkins 中运行条件步骤

    我正在尝试在詹金斯创建一个两步工作 我希望只有在第一步失败时才运行第二步 第一步执行单元测试以查看我正在编译的代码是否良好 如果不是 那么我想在第二步中运行一些诊断 有条件的阶梯插头似乎是一个不错的选择 但是 我无法弄清楚如何使用条件步骤插
  • .net core 项目依赖项 - 黄色三角形

    我的 Net Core 项目的依赖项上有一个黄色三角形 但是当我打开它时 所有子条目都没有黄色三角形 当我将鼠标悬停在依赖项上时 我没有看到任何工具提示告诉我出了什么问题 如何检查导致出现此黄色三角形的原因 我按照 oandreeeee 的
  • Lambda 和内存泄漏:寻找替代方法

    Edit 如果一位有能力验证此类事情的经验丰富的程序员向我展示该方法不会出现内存泄漏的证据 我将不胜感激 我已经将它引入到我的许多编码工作中 但我心中仍然有一个小疑问 不幸的是我不够好 不知道调查它的工具 原来的 我最近了解到 lambda
  • Octave - .m 文件编译器?

    我知道与Matlab可以将脚本 函数编译为可执行文件 然后与 Matlab 编译器运行时一起成为独立版本 有什么可能的方法编译与 Octave 相关的 m 文件作为可执行程序 不再需要 m 文件来运行 我想要一个独立版本的脚本 可以与八度库
  • 索引 16 处的路径中存在非法字符[重复]

    这个问题在这里已经有答案了 我在 RAD 中收到以下错误 java net URISyntaxException Illegal character in path at index 16 file E Program Files IBM
  • 在页面加载时获取ajax哈希url

    假设我在进行 ajax 调用时设置了一个哈希值 例子 http example com hash html http example com hash html 如果我加载另一个页面并单击后退按钮 我将如何检测哈希值并在加载时提取 url
  • CodeIgniter 的重写规则不起作用

    我已经安装了一个干净的 Apache2 加上 PHP 和 MySQL 服务器并启用了mod rewrite在阿帕奇配置中 我添加了 htaccess文件以从 url 中删除 index php 如 CodeIgniter wiki 中所述
  • TypeORM 是否为不同存储库提供事务?

    目前 三个不同的存储库需要将某些内容作为单个事务进行处理 我的服务代码写如下 但与我想象的不同 每个存储库都生成自己的事务 我怎么解决这个问题 TrimService Injectable export class TrimService
  • 如何使用 Python Etsy HTTP API 方法添加新项目?

    我正在尝试使用 Etsy API 在我的商店中添加新列表 在文档部分它说 下面的部分如何做到这一点 首先仅供参考 我以前从未使用过 HTTP 方法 所以我不确定如何设置代码以添加新项目 链接到 Etsy API 页面https www et
  • 如何检查子字符串是否包含“apple”中的所有字母

    如果我有字符串 axplpett 我想返回 true 因为它的子字符串 axplpe 包含 apple 的所有字母 我本来想使用set方法 但是苹果有重复字符 就这么简单 string axplpett test apple all str
  • 在母版页上使用时,ASP.Net 菜单控件呈现不正确

    我正在努力寻找 ASP Net 菜单控件与母版页结合使用时出现的奇怪问题的解决方案 当用户导航到某个页面时 via 菜单 继承自母版页 整个菜单只是展开并在屏幕上闪烁 立即折叠并呈现页面 导致屏幕上出现一些闪烁 让用户感到烦恼 现在 为此建
  • 如何使用 Jersey REST 序列化 Java 原语

    在我的应用程序中 我使用 Jersey REST 来序列化复杂对象 这工作得很好 但有一些方法只返回 int 或 boolean Jersey 无法处理原始类型 据我所知 可能是因为它们没有注释 并且 Jersey 没有默认注释 我通过创建
  • iOS 8 用户之间的数据共享

    我是 iOS 新手 我需要创建一个小型应用程序 允许注册用户在他们之间共享特定数据 我正在寻找最佳解决方案 我知道我可以创建一个服务器 它处理用户身份验证 推送通知以及在它们之间共享数据 但也许有一种更简单 更好的方法 我看到iOS 8引入
  • PostgreSQL 中写入操作的 CTE 并行查询

    From PostgreSQL 9 6 发行说明 https www postgresql org docs 9 6 static release 9 6 html AEN130398 只有通过顺序扫描访问驱动表的严格只读查询才能并行化 我
  • Jboss 4.2 类加载

    我有一个罐子server default lib其中包含Foo class Bar class 我的班级也有同样的班级application WEB INF classes部署在server default deploy and Examp
  • 批处理文件运行时显示不确定的 JProgressBar

    我已经浏览 SO 和谷歌一段时间来寻找这个问题的答案 但我似乎找不到真正有效的答案 我将从头开始 我创建了一个 Java 类 其方法在后台运行批处理文件 不出现命令窗口 该程序运行良好 但最终用户会有点困惑 因为批处理文件需要一段时间才能完