我一直在浏览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()等待进程时,屏幕上没有任何内容。我只是希望向用户显示进程仍在运行的内容。思考?谢谢!
答案 0 :(得分:10)
您可以在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();
}
});
}
}