显示警报时失败的javafx任务

时间:2016-12-29 14:45:55

标签: java javafx-2

鉴于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?我怎么能改变它?

0 个答案:

没有答案