JavaFx - Updating GUI

后端 未结 1 1826
攒了一身酷
攒了一身酷 2020-11-27 23:13

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.

However, it only

相关标签:
1条回答
  • 2020-11-27 23:35

    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.

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题