将 System.out 重定向到 JavaFX 中的 TextArea

更新:

仍然有同样的问题,修改了主应用代码的来源:http://pastebin.com/fLCwuMVq

一定有什么东西阻止了UI,但它做了各种各样的事情(异步xmlrpc请求,异步http请求,文件io等),我尝试把它全部放进去,但它没有帮助。CoreTestrunLater

更新 2:

我验证了代码正确运行并生成输出,但UI组件无法长时间显示它

更新 3:

好吧,我修好了。我不知道为什么,但是没有关于JavaFX的指南说过这一点,它非常重要:

始终将程序逻辑放在与 Java FX 线程不同的线程中


我曾使用Swing's进行过这项工作,但由于某种原因,它不适用于JavaFX。JTextArea

我尝试调试,它并在每次写入后返回似乎正确写入它的字符,但GUI中的实际情况没有显示任何文本。.getText()TextArea

我是否忘了以某种方式刷新它或其他东西?

TextArea ta = TextAreaBuilder.create()
    .prefWidth(800)
    .prefHeight(600)
    .wrapText(true)
    .build();

Console console = new Console(ta);
PrintStream ps = new PrintStream(console, true);
System.setOut(ps);
System.setErr(ps);

Scene app = new Scene(ta);
primaryStage.setScene(app);
primaryStage.show();

和类:Console

import java.io.IOException;
import java.io.OutputStream;

import javafx.scene.control.TextArea;

public class Console extends OutputStream
{
    private TextArea    output;

    public Console(TextArea ta)
    {
        this.output = ta;
    }

    @Override
    public void write(int i) throws IOException
    {
        output.appendText(String.valueOf((char) i));
    }

}

注意:这是基于这个答案的解决方案,我删除了我不关心但未经修改的位(除了从Swing更改为JavaFX),它有相同的结果:数据写入UI元素,屏幕上没有数据显示。


答案 1

您是否尝试过在UI线程上运行它?

public void write(final int i) throws IOException {
    Platform.runLater(new Runnable() {
        public void run() {
            output.appendText(String.valueOf((char) i));
        }
    });
}

编辑

我认为你的问题是你在GUI线程中运行了一些长任务,这将冻结所有内容,直到它完成。我不知道是什么

CoreTest t = new CoreTest(installPath);
t.perform();

确实如此,但如果需要几秒钟,您的 GUI 将不会在这几秒钟内更新。您需要在单独的线程中运行这些任务。

为了记录,这工作正常(我已经删除了文件和CoreTest位):

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws IOException {

        TextArea ta = TextAreaBuilder.create().prefWidth(800).prefHeight(600).wrapText(true).build();
        Console console = new Console(ta);
        PrintStream ps = new PrintStream(console, true);
        System.setOut(ps);
        System.setErr(ps);
        Scene app = new Scene(ta);

        primaryStage.setScene(app);
        primaryStage.show();

        for (char c : "some text".toCharArray()) {
            console.write(c);
        }
        ps.close();
    }

    public static void main(String[] args) {
        launch(args);
    }

    public static class Console extends OutputStream {

        private TextArea output;

        public Console(TextArea ta) {
            this.output = ta;
        }

        @Override
        public void write(int i) throws IOException {
            output.appendText(String.valueOf((char) i));
        }
    }
}

答案 2