JavaFx-更新GUI

JavaFx-更新GUI,java,javafx,Java,Javafx,我只想在程序运行时更新标签。我正在读取一些文件,我希望它显示正在读取的文件的名称 但是,它仅使用下面的代码显示最后一个文件(基本上,GUI在整个过程完成之前不会响应): 我有大约4-5个文件,我只想显示名称 我看到了一个类似的问题 ,最佳答案建议如下: Label myLabel = new Label("Start"); //I declared this outside the function so dont worry myLabel.textProperty().bind(valueP

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

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

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

我看到了一个类似的问题 ,最佳答案建议如下:

Label myLabel = new Label("Start"); //I declared this outside the function so dont worry
myLabel.textProperty().bind(valueProperty);
但是valueProperty是StringProperty,我无法将字符串转换为字符串属性


我也看到了,但是OP可以根据行动更新标签。我真的没有执行任何操作?

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

下面是一个简单的例子,我在每次迭代之间暂停250毫秒(模拟读取一个相当大的文件)。一个按钮将在FX应用程序线程中启动此功能(请注意,当此功能运行时,UI是如何无响应的-您不能在文本字段中键入)。另一个按钮使用
任务
在后台运行它,在FX应用程序线程上正确地安排对UI的更新

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.application.application;
导入javafx.concurrent.Task;
导入javafx.geometry.Insets;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.Label;
导入javafx.scene.control.TextField;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.VBox;
导入javafx.stage.stage;
公共类UpdateTaskDemo扩展了应用程序{
@凌驾
公共无效开始(阶段primaryStage){
标签=新标签();
Button runOnFXThreadButton=新建按钮(“在FX线程上更新”);
按钮runInTaskButton=新建按钮(“后台更新任务”);
HBox按钮=新的HBox(10,RunOnTextThreadButton,runInTaskButton);
按钮。设置填充(新插图(10));
VBox root=新的VBox(10,标签,按钮,新文本字段());
根。设置填充(新插图(10));
runOnFXThreadButton.setOnAction(事件->{
对于(int i=1;i{
任务=新任务(){
@凌驾
public Void call()引发异常{
对于(inti=1;i label.setText(newMessage));
新线程(任务).start();
});
原始阶段。设置场景(新场景(根,400225));
primaryStage.show();
}
公共静态void main(字符串[]args){
发射(args);
}
}

这听起来可能是一个线程问题,但仅仅用几个代码片段是不可能判断的。你能从头开始创建一个演示问题的线程吗?但我只有一个线程。好的。我会添加更多细节如果你在FX应用程序线程上运行整个进程,那么这就是问题所在。为什么是pro如果我在一个线程上运行所有内容会出现问题?我的意思是我单击一个单选按钮。单击提交。获取目录中的文件。遍历它们并显示我正在遍历的文件
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);
    }
}