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

查看:137
本文介绍了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如何无响应 - 您无法在文本字段中键入内容)。另一个按钮使用任务在后台运行它,正确安排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天全站免登陆