各位程序员好。
所以我终于开始使用 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 库并制作了一个显示该进度的进度对话框。(对话独库)
此对话框需要一个 Worker,然后将显示进度。一旦 Worker State 更改为 Scheduled 或 Running,它将自动显示。我现在的问题是这个对话框永远不会显示,因为在状态更改为其中之一之前调用了调用方法。
我做了一些调试,似乎在 Task 类中,State 更改将通过 Platform.runLater() 方法应用,然后 call() 方法被直接调用(没有 runLater),我的系统似乎在 State 更改之前安排了这个.
所以我的问题是,有人可以重现或有类似的问题吗?如果是,Task 类是否按预期工作或者这可能是一个错误(比如 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;
现在我期望的顺序是在执行 call() 方法之前将状态设置为首先 SCHEDULED 然后 RUNNING 。然而,在我的情况下,它总是先调用(),然后再过一段时间它会改变状态。
例子:
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