0
我有两个任务,一个用于更改屏幕不透明度,另一个用于执行复杂计算。我想计算开始后,才在屏幕衰落实际上已经改变了,所以我写了下面的:JavaFX中的并发 - 任务未完成
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
stage.getScene().getRoot().setOpacity(0.2);
stage.show();
return null;
}
};
Task<Void> task2 = new Task<Void>() {
@Override
protected Void call() throws Exception {
// Complex computation
return null;
}
};
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent paramT) {
// this busy waiting line was added in attempt to force the
// fading before beginning second task
while (stage.getScene().getRoot().getOpacity() != 0.2) {}
stage.show();
Platform.runLater(task2);
}
});
task2.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent paramT) {
stage.getScene().getRoot().setOpacity(1);
stage.show();
}
});
task.run();
但是,有时我看到的计算开始和屏幕,它的完成后才消失。有时它确实起作用。所以我认为这里有一个线程问题。注意:当我处于调试模式并停止执行每个任务时,它每次都能正常工作。在第二项任务开始之前可以做些什么来强制屏幕褪色?
编辑: 至于建议,我改变了代码如下:
Task<Void> task1 = new Task<Void>() {
@Override
protected Void call() throws Exception {
// Long computation
return null;
}
};
Task<Void> task = new Task<Void>() {
@Override
protected Void call() throws Exception {
FadeTransition ft = new FadeTransition(Duration.millis(1), stage.getScene().getRoot());
ft.setFromValue(1.0);
ft.setToValue(0.1);
ft.setCycleCount(1);
//ft.setAutoReverse(true);
ft.play();
ft.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
new Thread(task1).run();
}
});
return null;
}
};
task1.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent paramT) {
FadeTransition ft1 = new FadeTransition(new Duration(0.1), stage.getScene().getRoot());
ft1.setFromValue(0.1);
ft1.setToValue(1.0);
ft1.setCycleCount(1);
//ft.setAutoReverse(true);
ft1.play();
//stage.show();
}
});
new Thread(task).run();
我仍然看到相同的行为。
有这么多错在这里很难知道从哪里开始。你的任务都不会在后台线程中执行(第一个,你只需调用'run(...)',它将在当前线程中执行它;在第二个中,你可以用它来执行它FX应用程序线程调用'Platform.runLater(...)')。你的第一个'Task'更新UI,如果你在后台线程中运行,这将是非法的。 'setOpacity(...)'不会像您期望的那样创建“淡入淡出”,但会立即改变不透明度。你的'onSucceeded'阻止执行,这会冻结UI。 –
如果您想要“淡入淡出”,请使用['FadeTransition]](http://docs.oracle.com/javase/8/javafx/api/javafx/animation/FadeTransition.html)。启动淡入转场的'onFinished'处理程序中的第二项任务。这里不需要屏蔽(因为淡入淡出已经完成)。在后台线程中启动执行计算的任务,或将其传递给执行程序。请参阅['任务'Javadocs](http://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html)。 –