在Platform.runLater可运行后添加延迟

0 java javafx delay

我是javaFX的初学者,可能我错过了一些东西,但是我的问题是:我应该按顺序在我的gui应用程序中显示一些变化.

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

public void updateGui()
{
    Platform.runLater(() -> {
        doFirstStuff();
        doSecondStuff();
        doThirdStuff();
    });
}
Run Code Online (Sandbox Code Playgroud)

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

我的尝试是:

Thread.sleep(1000);
Run Code Online (Sandbox Code Playgroud)

在每个方法调用之后,但由于该线程是JavaFX应用程序线程,结果很糟糕.

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

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

() -> {
    Platform.runLater(() -> {
        doFirstStuff();
    });
    Thread.sleep(1000);
});
Run Code Online (Sandbox Code Playgroud)

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

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

Jam*_*s_D 8

最简单的方法就是使用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);
}
Run Code Online (Sandbox Code Playgroud)

我假设这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();
}
Run Code Online (Sandbox Code Playgroud)

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

  • @GoXr3Plus 这是一个[方法参考](https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html)。它相当于`Platform.runLater(() ->时间线.play())`。由于`timeline.play()`的签名(无参数,无返回值)与`Runnable`中抽象方法的签名相同,你可以简单地传递一个方法引用来代替`Runnable.run的实现()`。 (2认同)