在任务中更新消息会挂起应用程序

时间:2018-07-07 15:55:46

标签: java javafx java.util.concurrent

我正在使用后台Thread运行我的加载代码,并希望将MessageProperty中的Task绑定到标签。

但是,在调用updateMessage()时,任务挂起了;该消息永远不会更新,并且下一行代码不会执行。

这使用的是JDK 1.10.1。这是MCVE:

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {

        VBox root = new VBox(10);
        Label label = new Label("Message");
        root.getChildren().add(label);

        primaryStage.setScene(new Scene(root));

        Task loadingTask = new LoadingTask();
        Thread loadingThread = new Thread(loadingTask);
        loadingThread.setDaemon(true);

        label.textProperty().bind(loadingTask.messageProperty());
        loadingThread.start();

        primaryStage.setWidth(200);
        primaryStage.setHeight(200);
        primaryStage.show();
    }
}

class LoadingTask<Void> extends Task {
    @Override
    protected Object call() throws Exception {
        System.out.println("Loading task ...");
        updateMessage("Loading task ...");
        System.out.println("Message: " + getMessage());

        return null;
    }
}

输出:

Loading task ...

第二个System.out.println()从未执行。

编辑:

我在MCVE中添加了一个简单的GUI,其标签绑定到MessageProperty。标签确实更新为显示“正在加载任务...”,但控制台输出保持不变;调用updateMessage()方法后的代码不会执行。

第二次编辑:

我运行了步骤调试器,并且从IllegalStateException类中抛出了Task:“只能从FX Application Thread中使用任务”

我不确定这是什么意思,因为要点是在另一个线程上运行此任务...

1 个答案:

答案 0 :(得分:3)

您唯一的问题是,不得从FX UI线程以外的其他线程访问getMessage()。尝试Platform.runLater(() -> System.out.println("Message: " + getMessage()));