JavaFX TextArea appendText适用于初始化,但不适用于其他地方 [英] JavaFX TextArea appendText works in initialize but not elsewhere

查看:2496
本文介绍了JavaFX TextArea appendText适用于初始化,但不适用于其他地方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简单的问题,但它一直让我发疯。

Simple enough problem but it's been driving me crazy.

在我的程序中,我有 TextArea ,定义为:

In my program I have a TextArea, defined as:

<TextArea fx:id="output" editable="false" prefHeight="300.0" prefWidth="200.0" text="Output" GridPane.columnSpan="2" GridPane.rowIndex="4" />





@FXML private TextArea output;

...

public void initialize(URL url, ResourceBundle rb) {
    output.setText("Test"); //Test appears correctly in output
    ...
}

@FXML
public void download() {
    String outputTemplate = templateField.getText();
    String url = urlField.getText();
    System.out.println("Downloading from " + url);
    try {
        Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
        BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line); //Prints as expected
            output.appendText(line + "\n"); //Has no effect
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

有关如何显示文字的任何想法都会很棒,我之前已经在不同的程序上完成了这个,只是出于某种原因,这次它是非常好的

Any ideas on how to get the text to appear would be great, I've done this before on different programs, just for some reason, this time it's being cantankerous

编辑:进一步修改后,它实际上将打印出来结果,但只有在 Process 结束并退出循环之后。

Upon further tinkering, it actually will print out the results, but only after the Process ends and it exits the loop.

推荐答案

UI中显示的文字在布局脉冲上发生变化。布局脉冲在JavaFX应用程序线程上完成。事件处理程序(如 download 方法)在同一个线程上运行,有效地阻止它在完成之前进行任何布局或处理以及其他事件。这就是为什么你不应该使用longrunning任务来阻止这个线程,而是在不同的线程上执行它们。

The text shown in the UI changes on a layout pulse. Layout pulses are done on the JavaFX application thread. Event handlers, like your download method run on the same thread effectively preventing it from doing any layouting or processing and other events until it completes. This is why you shouldn't block this thread with longrunning tasks, but execute them on a different thread.

由于UI的更新应该从应用程序线程完成,使用 Platform.runLater 附加文字:

Since updates to the UI should be done from the application thread, use Platform.runLater to append the text:

@FXML
public void download() {
    String outputTemplate = templateField.getText();
    String url = urlField.getText();
    Runnable r  = () -> {
        System.out.println("Downloading from " + url);
        try {
            Process down = Runtime.getRuntime().exec("youtube-dl -o \"" + outputTemplate + "\" " + url);
            BufferedReader reader = new BufferedReader(new InputStreamReader(down.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line); //Prints as expected
                final String printText = line + "\n";

                // append the line on the application thread
                Platform.runLater(() -> output.appendText(printText));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    };
    // run task on different thread
    Thread t = new Thread(r);
    t.start();
}

这篇关于JavaFX TextArea appendText适用于初始化,但不适用于其他地方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆