JavaFx - 更新 GUI [英] JavaFx - Updating GUI

查看:21
本文介绍了JavaFx - 更新 GUI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要的只是在我的程序运行时更新标签.我正在阅读一些文件,我希望它显示正在阅读的文件的名称.

All I wanted is to update a label as my program is running. I am reading some files and I wanted it to display the name of the file is was reading.

然而,它只使用下面的代码显示最后一个文件(基本上GUI在整个过程完成之前不会响应):

However, it only displays the last file using the code below (basically GUI doesn't respond until the whole process is completed):

static Text m_status_update = new Text(); //I declared this outside the function so dont worry
m_status_update.setText("Currently reading " + file.getName());

我有大约 4-5 个文件,我只想显示名称.

I got around 4-5 files and I just want to display the name.

我看到了一个类似的问题 在 JavaFx 标签中显示变化的值,最佳答案推荐如下:

I saw a similar question Displaying changing values in JavaFx Label , the best answer recommended the following:

Label myLabel = new Label("Start"); //I declared this outside the function so dont worry
myLabel.textProperty().bind(valueProperty);

但是 valueProperty 是 StringProperty,我无法将字符串转换为字符串属性.

However the valueProperty is a StringProperty and I am stuck converting a string into a string property.

另外,我看到了这个 在 JAVAFX 中刷新标签,但是 OP可以根据动作更新标签.我真的没有任何动作吗?

Also, I saw this Refresh label in JAVAFX , but the OP could update the label based on action. I really dont have any action going on?

推荐答案

如果您在 FX 应用程序线程上运行整个进程,那么该线程(实际上)就是用于显示 UI 的同一线程.如果 UI 的显示和您的文件迭代过程都在同一线程中运行,则一次只能发生一个.因此,您可以在该过程完成之前阻止 UI 更新.

If you run the entire process on the FX Application thread, then that is (effectively) the same thread that is being used to display the UI. If both the display of the UI, and your file iteration process are running in the same thread, only one can happen at once. So you prevent the UI from updating until the process is complete.

这是一个简单的例子,我在每次迭代之间暂停 250 毫秒(模拟读取一个相当大的文件).一个按钮在 FX 应用程序线程中启动它(注意 UI 在运行时没有响应 - 您不能在文本字段中输入).另一个按钮使用 Task 在后台运行它,在 FX 应用程序线程上正确安排对 UI 的更新.

Here's a simple example where I just pause for 250 milliseconds between each iteration (simulating reading a reasonably large file). One button launches this in the FX Application thread (notice how the UI is unresponsive while this runs - you can't type in the text field). The other button uses a Task to run it in the background, properly scheduling updates to the UI on the FX Application thread.

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;


public class UpdateTaskDemo extends Application {

    @Override
    public void start(Stage primaryStage) {
        Label label = new Label();
        Button runOnFXThreadButton = new Button("Update on FX Thread");
        Button runInTaskButton = new Button("Update in background Task");
        HBox buttons = new HBox(10, runOnFXThreadButton, runInTaskButton);
        buttons.setPadding(new Insets(10));
        VBox root = new VBox(10, label, buttons, new TextField());
        root.setPadding(new Insets(10));

        runOnFXThreadButton.setOnAction(event -> {
            for (int i=1; i<=10; i++) {
                label.setText("Count: "+i);
                try {
                    Thread.sleep(250);
                } catch (InterruptedException exc) {
                    throw new Error("Unexpected interruption");
                }
            }

        });

        runInTaskButton.setOnAction(event -> {
            Task<Void> task = new Task<Void>() {
                @Override 
                public Void call() throws Exception {
                    for (int i=1; i<=10; i++) {
                        updateMessage("Count: "+i);
                        Thread.sleep(250);
                    }
                    return null ;
                }
            };
            task.messageProperty().addListener((obs, oldMessage, newMessage) -> label.setText(newMessage));
            new Thread(task).start();
        });

        primaryStage.setScene(new Scene(root, 400, 225));
        primaryStage.show();
    }

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

这篇关于JavaFx - 更新 GUI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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