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

我一直在浏览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()等待这个过程时,屏幕上没有任何东西。 我只想让用户看到一个进程仍在运行。 思考? 谢谢!

您可以在SwingWorker的后台运行ProcessBuilder ,如下所示,以获得输出和进度条。

图片

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