当前位置: 首页 > 面试题库 >

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

曹恩
2023-03-14
问题内容

我已经在SO和google上浏览了一段时间,以找到该问题的答案,但是我似乎找不到真正有效的方法。我将从头开始:

我用一个在后台运行批处理文件的方法创建了一个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,如下图所示,得到既输出和一个进度条。

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();
            }
        });
    }
}


 类似资料:
  • 我已经浏览了SO和谷歌一段时间,想找到这个问题的答案,但我似乎找不到一个真正有效的答案。我将从头开始: 我用一个方法创建了一个Java类,该方法在后台运行一个批处理文件(命令窗口不会出现)。该程序运行得很好,只是最终用户会感到有点困惑,因为批处理文件需要一段时间才能完成——用户将不知道该程序是否仍在运行。批处理脚本完成执行后,会出现一个消息对话框,说明它已完成,但在方法运行和对话框出现之间的一段时

  • 问题内容: 我正在尝试从Java可执行文件运行另一个目录中的批处理文件。我有以下代码: 结果是程序在运行该程序的根目录中打开一个cmd窗口,并且无法访问我提供的文件路径。 问题答案: 而不是,您需要使用方法签名: 但就我个人而言,我会改用,它稍微冗长一些,但比容易使用和调试。

  • 我试图从我的Java可执行文件运行另一个目录中的批处理文件。我有以下代码: 结果是,程序在运行程序的根目录中打开了一个cmd窗口,无法访问我提供的文件路径。

  • 我想使用java程序运行一个批处理文件,当我双击. bat文件时,它要求我输入“D”,然后在C驱动器中创建一些文件夹,以下是. bat文件的内容: 我的Java代码如下: 它没有给我任何错误,但它既没有要求我输入任何值,也没有创建任何文件夹。 我想知道在java代码中我需要做什么,这样它会要求我输入' D ',然后输入。bat文件应该以正常流程继续。 感谢任何帮助。

  • 当我运行这段代码时,我只得到命令提示。。bat文件没有运行。如何使用这段代码执行批处理文件? 提前致谢

  • 问题内容: 我需要从Java执行批处理脚本,该脚本执行以下操作 1)一旦启动,它将执行一个冗长的任务(最多几秒钟)。 2)此后,它显示提示“密码:”。 3)然后,用户输入密码并按Enter键。 4)然后,脚本完成其工作。 我知道如何从Java启动脚本,知道如何在Java中读取批处理脚本的输出,但是我不知道如何等待密码提示出现(如何知道批处理脚本正在等待密码条目)。 因此,我的问题是:如何知道批处理