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

我已经在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();

}

});

}

}

以上是 Java批处理文件运行时显示不确定的JProgressBar 的全部内容, 来源链接: utcz.com/qa/411015.html

回到顶部