JavaFx – 更新GUI

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

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

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个文件,我只想显示名称。

我看到一个类似的问题在JavaFx Label中显示更改值 ,最佳答案建议如下:

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

但是,valueProperty是一个StringProperty,我很难将字符串转换为字符串属性。

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

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

这是一个简单的例子,我在每次迭代之间暂停250毫秒(模拟读取一个相当大的文件)。 一个按钮在FX应用程序线程中启动它(注意在运行时UI如何无响应 – 您无法在文本字段中键入内容)。 另一个按钮使用Task在后台运行它,正确安排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 task = new Task() { @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); } }