Подтвердить что ты не робот

Перенаправление System.out в TextArea в JavaFX

Обновление:

Все еще имея ту же проблему, пересмотренный источник основного кода приложения: http://pastebin.com/fLCwuMVq

В CoreTest должно быть что-то, что блокирует пользовательский интерфейс, но делает всевозможные вещи (запросы async xmlrpc, асинхронные HTTP-запросы, файл io и т.д.), я попытался поместить все это в runLater, но он не помогает.

Обновление 2:

Я проверил выполнение кода и корректно выдал результат, но компонент пользовательского интерфейса не может отображать его на протяжении веков

Обновление 3:

ОК, я исправил его. Я не знаю, почему, но ни один гид о JavaFX не сказал об этом, и его очень важно:

Всегда помещайте свою логику программы в отдельный поток из потока Java FX


Я работал с Swing JTextArea, но по какой-то причине он не работает с JavaFX.

Я попробовал отладку, и он и выполнил .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) он имел тот же результат: данные, записанные в элемент пользовательского интерфейса, без данных, отображаемых на экране.

4b9b3361

Ответ 1

Вы пытались запустить его в потоке пользовательского интерфейса?

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

ИЗМЕНИТЬ

Я думаю, ваша проблема в том, что вы запускаете несколько длинных задач в потоке графического интерфейса пользователя, который будет заморозить все до тех пор, пока он не завершится. Я не знаю, что

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

но если это займет несколько секунд, ваш графический интерфейс не будет обновляться в течение этих нескольких секунд. Вам нужно запустить эти задачи в отдельном потоке.

Для записи это прекрасно работает (я удалил файлы и биты 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));
        }
    }
}