我正在尝试制作一个Java程序,用户可以从其计算机中选择任何.class
或.jar
文件。然后,我的程序将弹出一个JInternalFrame
,其中包含JEditorPane
作为控制台,捕获用户程序的任何控制台输出。请注意,我不想仅捕获System.err或System.out调用,而是捕获转到控制台的所有PrintStream调用。
(来自IDE-Style program running的个别问题)
答案 0 :(得分:3)
您可以使用System.setOut
抓住System.out
打印的所有内容,如下所示:
import java.io.*;
class SystemOutLogging {
public static void main(String[] args) throws IOException,
ClassNotFoundException {
final PrintStream original = System.out;
System.setOut(new PrintStream("programlog.txt") {
public void println(String str) {
process(str + "\n");
}
public void print(String str) {
process(str);
}
private void process(String str) {
// Fill some JEditorPane
original.println("Program printed: \"" + str + "\"");
}
});
System.out.print("Hello ");
System.out.println(" World");
}
}
打印:
Program printed: "Hello "
Program printed: " World
"
(System.setErr
和System.setIn
的工作方式类似。)
如果你想抓住“子程序”通过System.out.println
打印的东西,你就会遇到麻烦,因为System.out
是静态的,所以如果你启动多个“子程序”,你最终会得到一团糟(因为你不能将单独的System
类交给每个子程序。)
在这样的情况下,我真的认为通过ProcessBuilder启动一个单独的流程会更好。可以轻松记录生成的过程的标准输入/输出流。
(p.s。当我考虑它时,你可能会检查println
实现中的当前线程组,并从中确定实际调用println
方法的子程序)
答案 1 :(得分:0)
如果您使用Runtime.exec()启动用户的.jar文件,您将获得一个Process对象。该对象将允许您访问已启动的进程System.out,System.in和System.err流。
请参阅:http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Process.html
您可以从err和out流中读取,并使用通常的setText类型方法附加到JEditorPane。