JavaFX任务状态未正确更新?

时间:2014-09-28 17:10:36

标签: java javafx task javafx-8 controlsfx

Hello其他程序员。

所以我终于开始使用JavaFX并发现一些不安静的东西似乎是正确的。 如果我覆盖了我的任务的call()方法然后运行它,则该任务的状态将在呼叫完成后开始更新。

我的代码看起来像这样

Task<Boolean> myTask = new Task<Boolean>() {
    @Override
    protected Boolean call() throws Exception {
        try {
             // do stuff
             return true;
        } catch (Exception e){
             return false;
        }
    }
}

在try块中,我有一些需要几秒钟才能完成的调用,并且我不希望我的GUI在此期间简单地阻止。然而,由于无法进一步发展,我使用了ControlsFX库并创建了一个显示它的进度对话框。 (Dialogs Doku

此对话框需要一名工人,然后会显示进度。一旦工作人员状态更改为“计划”或“正在运行”,它将自动显示。我现在的问题是,由于在状态更改为其中之一之前调用了调用方法,因此永远不会显示此对话框。

我做了一些调试,似乎在Task类中,State更改将应用​​Platform.runLater()方法,然后直接调用call()方法(没有runLater),我的系统似乎在之前调度国家变化。

所以我的问题是,有人可以复制或有类似的问题吗? 如果是的话,Task类是否按预期工作,或者这可能是一个bug(比如call()也必须通过runLater方法调用)?

帮助真的很感激:) 请原谅我的第二语言英语

以下是Task类的代码

task.runLater(() -> {
    task.setState(State.SCHEDULED);
    task.setState(State.RUNNING);
});
 // Go ahead and delegate to the wrapped callable
try {
    final V result = task.call();
    if (!task.isCancelled()) {
        task.runLater(() -> {
        task.updateValue(result);
        task.setState(State.SUCCEEDED);
    });
    return result;

现在我预期的顺序是将状态设置为第一个SCHEDULED,然后在执行call()方法之前运行。在我的情况下,它总是首先调用()然后一段时间后它会改变状态。

示例:

package test;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.stage.Stage;

public class TaskTest extends Application {

    @Override
    public void start(Stage primaryStage) {
        Task<Void> myTask = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                System.out.println("Executing stuff");
                return null;
            }
        };

        myTask.stateProperty().addListener(new ChangeListener<Worker.State>() {

            @Override
            public void changed(
                    ObservableValue<? extends javafx.concurrent.Worker.State> observable,
                    Worker.State oldValue,
                    Worker.State newValue) {
                System.out.println("State change: " + oldValue + " -> " + newValue);

            }
        });

        Executors.newSingleThreadExecutor().execute(myTask);

        try {
            myTask.get();
        } catch (InterruptedException | ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

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

结果:

Executing stuff
State change: READY -> SCHEDULED
State change: SCHEDULED -> RUNNING
State change: RUNNING -> SUCCEEDED

预期:

State change: READY -> SCHEDULED
State change: SCHEDULED -> RUNNING
Executing stuff
State change: RUNNING -> SUCCEEDED

0 个答案:

没有答案