在Platform.runLater runnable

时间:2016-08-30 19:22:41

标签: java javafx delay

我是javaFX的初学者,可能我错过了什么,但我的问题是:我应该在我的gui应用程序中依次显示一些变化。

我的代码看起来像这样(每个方法在gui中执行更改,但最终结果由最后一个方法给出):

public void updateGui()
{
    Platform.runLater(() -> {
        doFirstStuff();
        doSecondStuff();
        doThirdStuff();
    });
}

如果在每个方法的执行之间有一点延迟(1,2或3秒)给用户时间以查看应用程序中发生的事情,那将是很好的。

我的尝试被放了:

Thread.sleep(1000);

在每次调用方法之后,但由于该线程是JavaFX Application Thread,结果很糟糕。

我脑海中现在出现的另一个解决方案是:

使用Runnable执行另一个线程中的每个方法,如下所示:

() -> {
    Platform.runLater(() -> {
        doFirstStuff();
    });
    Thread.sleep(1000);
});

并在updateGui()中以newSingleThreadExecutor()提交任务并等待每项任务的终止。但我不知道,这似乎不是一个好的解决方案。

实现目标的最佳方式是什么?

1 个答案:

答案 0 :(得分:7)

最简单的方法就是使用Timeline

public void updateGui() {
    final KeyFrame kf1 = new KeyFrame(Duration.seconds(0), e -> doFirstStuff());
    final KeyFrame kf2 = new KeyFrame(Duration.seconds(1), e -> doSecondStuff());
    final KeyFrame kf3 = new KeyFrame(Duration.seconds(2), e -> doThirdStuff());
    final Timeline timeline = new Timeline(kf1, kf2, kf3);
    Platform.runLater(timeline::play);
}

我假设在后台线程上调用updateGui()(否则只需删除Platform.runLater(...)并直接调用timeline.play())。

如果你真的想弄脏线程,你可以用

来实现同样的目标(或多或少)
public void updateGui() {

    Thread thread = new Thread(() -> {
        try {
            Platform.runLater(() -> doFirstStuff());
            Thread.sleep(1000);
            Platform.runLater(() -> doSecondStuff());
            Thread.sleep(1000);
            Platform.runLater(() -> doThirdStuff());
        } catch (InterrupedException exc) {
            // should not be able to get here...
            throw new Error("Unexpected interruption");
        }
    };
    thread.start();
}

但我认为对于这样的用例,Timeline(或动画API的其他部分)更清晰(并且使用更少的资源,因为它们不会创建新线程)。