鉴于https://stackoverflow.com/a/22098572/409976,我尝试修改它,以便在完成倒计时后显示Alert
。通过"完成,"我的意思是它已达到0。
package net;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ProgressTracker extends Application {
final int N_SECS = 3;
@Override
public void start(Stage stage) throws Exception {
Task task = createTask();
stage.setScene(
new Scene(
createLayout(
task
)
)
);
stage.show();
new Thread(task).start();
}
private Task<Alert> createTask() {
return new Task<Alert>() {
@Override public Alert call() {
for (int i=0; i < N_SECS; i++) {
if (isCancelled()) {
break;
}
// uncomment updateProgress call if you want to show progress
// rather than let progress remain indeterminate.
// updateProgress(i, N_SECS);
updateMessage((N_SECS - i) + "");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
return null;
}
}
updateMessage(0 + "");
updateProgress(N_SECS, N_SECS);
return new Alert(Alert.AlertType.INFORMATION, "whoops");
}
};
}
private HBox createLayout(Task<Alert> task) {
HBox layout = new HBox(10);
layout.getChildren().setAll(
createProgressIndicator(task),
createCounter(task)
);
layout.setAlignment(Pos.CENTER_RIGHT);
layout.setPadding(new Insets(10));
return layout;
}
private ProgressIndicator createProgressIndicator(Task<Alert> task) {
ProgressIndicator progress = new ProgressIndicator();
progress.progressProperty().bind(task.progressProperty());
task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
System.out.println("success");
task.getValue().show();
}
});
task.setOnFailed(new EventHandler<WorkerStateEvent>() {
@Override
public void handle(WorkerStateEvent t) {
System.out.println("failed");
task.getValue().show();
}
});
return progress;
}
private Label createCounter(Task<Alert> task) {
Label counter = new Label();
counter.setMinWidth(20);
counter.setAlignment(Pos.CENTER_RIGHT);
counter.textProperty().bind(task.messageProperty());
counter.setStyle("-fx-border-color: forestgreen;");
return counter;
}
public static void main(String[] args) {
launch(args);
}
}
但是,运行它时会看到以下异常:
[info] Running net.ProgressTracker
[error] Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
[info] failed
[error] at net.ProgressTracker$3.handle(ProgressTracker.java:90)
[error] at net.ProgressTracker$3.handle(ProgressTracker.java:86)
[error] at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
[error] at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
[error] at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
[error] at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
[error] at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
[error] at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
[error] at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
[error] at javafx.event.Event.fireEvent(Event.java:198)
[error] at javafx.concurrent.EventHelper.fireEvent(EventHelper.java:219)
[error] at javafx.concurrent.Task.fireEvent(Task.java:1356)
[error] at javafx.concurrent.Task.setState(Task.java:707)
[error] at javafx.concurrent.Task$TaskCallable.lambda$call$501(Task.java:1453)
[error] at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
[error] at java.security.AccessController.doPrivileged(Native Method)
[error] at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
[error] at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
[error] at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
[error] at com.sun.glass.ui.gtk.GtkApplication.lambda$null$49(GtkApplication.java:139)
[error] at java.lang.Thread.run(Thread.java:745)
为什么task
失败了?其次,如何修复此代码以实际显示成功或失败的警报?
编辑
根据Omid的评论,&#34;使用task.getException()来了解失败的原因,&#34;我添加了以下打印输出:
System.out.println(t.getSource().getException());
它显示:
[info] java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-3
那么,这意味着我没有在FX应用程序线程上调用Alert#show
?我怎么能改变它?