显示警报时javafx任务失败

显示警报时javafx任务失败,java,javafx-2,Java,Javafx 2,给定,我试图修改它,以便在完成倒计时时显示警报。所谓“完成”,我的意思是它已经达到了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

给定,我试图修改它,以便在完成倒计时时显示
警报。所谓“完成”,我的意思是它已经达到了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);
    }
}
为什么
任务
失败?其次,如何修复此代码以实际显示成功或失败警报

编辑

Per的注释“使用task.getException()了解失败的原因”,我添加了以下打印输出:

System.out.println(t.getSource().getException())

它表明:

[info]java.lang.IllegalStateException:不在FX应用程序线程上;currentThread=Thread-3


那么,这意味着我不是在FX应用程序线程上调用
Alert#show
?我如何更改它?

查看堆栈跟踪,
NPE
来自L90:
task.getValue().show()。因此,我假设
task.getValue
null
。但是,您声称我的问题是重复的,这个问题并不能解释任务失败的原因。@Kevin Meredith使用
task.getException()
来了解任务失败的原因。
[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)