UPDATE: I found a crucial part to why this probably isn't working! I used System.setOut(out); where out is a special PrintStream to a JTextArea
这是代码,但我遇到的问题是,只有在我结束流程后才打印出信息。
public Constructor() {
main();
}
private void main() {
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
ProcessBuilder builder = new ProcessBuilder("java", textFieldMemory.getText(), "-jar", myJar);
Process process = builder.start();
InputStream inputStream = process.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream), 1);
String line;
while ((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
inputStream.close();
bufferedReader.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
}
当前输出:
Line 1
Line 2
Line 3
Line 4
Line 5
这是正确的输出,但是当我结束这个过程时它只被打印成一个大块。
有谁知道这是什么问题?如果是这样,你能帮我解释一下为什么会发生这种情况,请提前谢谢。
答案 0 :(得分:9)
在单独的线程中处理进程的输出流可能会有所帮助。您还希望在继续逻辑之前明确等待进程结束:
ProcessBuilder builder = new ProcessBuilder("java",
textFieldMemory.getText(), "-jar", myJar);
final Process process = builder.start();
final Thread ioThread = new Thread() {
@Override
public void run() {
try {
final BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
} catch (final Exception e) {
e.printStackTrace();
}
}
};
ioThread.start();
process.waitFor();
答案 1 :(得分:4)
基本上,从简单的信息来看,这听起来像是在执行流程并从事件调度线程中读取InputStream
。
任何阻止EDT的东西都会阻止它处理重绘请求,相反,你应该使用类似SwingWorker
的东西,它具有允许你用EDT更新UI的功能。
请查看Concurrency in Swing了解详情
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class PBDemo {
public static void main(String[] args) throws Exception {
new PBDemo();
}
public PBDemo() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
JTextArea ta = new JTextArea();
add(new JScrollPane(ta));
new ProcessWorker(ta).execute();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public interface Consumer {
public void consume(String value);
}
public class ProcessWorker extends SwingWorker<Integer, String> implements Consumer {
private JTextArea textArea;
public ProcessWorker(JTextArea textArea) {
this.textArea = textArea;
}
@Override
protected void process(List<String> chunks) {
for (String value : chunks) {
textArea.append(value);
}
}
@Override
protected Integer doInBackground() throws Exception {
// Forced delay to allow the screen to update
Thread.sleep(5000);
publish("Starting...\n");
int exitCode = 0;
ProcessBuilder pb = new ProcessBuilder("java.exe", "-jar", "HelloWorld.jar");
pb.directory(new File("C:\\DevWork\\personal\\java\\projects\\wip\\StackOverflow\\HelloWorld\\dist"));
pb.redirectError();
try {
Process pro = pb.start();
InputConsumer ic = new InputConsumer(pro.getInputStream(), this);
System.out.println("...Waiting");
exitCode = pro.waitFor();
ic.join();
System.out.println("Process exited with " + exitCode + "\n");
} catch (Exception e) {
System.out.println("sorry" + e);
}
publish("Process exited with " + exitCode);
return exitCode;
}
@Override
public void consume(String value) {
publish(value);
}
}
public static class InputConsumer extends Thread {
private InputStream is;
private Consumer consumer;
public InputConsumer(InputStream is, Consumer consumer) {
this.is = is;
this.consumer = consumer;
start();
}
@Override
public void run() {
try {
int in = -1;
while ((in = is.read()) != -1) {
// System.out.print((char) in);
consumer.consume(Character.toString((char)in));
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
}