Java 在Platform.runLater runnable之后添加延迟
我是javaFX的初学者,可能我遗漏了一些东西,但我的问题是:我应该按顺序显示gui应用程序中的一些更改 我的代码看起来是这样的,每个方法都会在gui中执行一次更改,但最终结果当然是由最后一个方法给出的:Java 在Platform.runLater runnable之后添加延迟,java,javafx,delay,Java,Javafx,Delay,我是javaFX的初学者,可能我遗漏了一些东西,但我的问题是:我应该按顺序显示gui应用程序中的一些更改 我的代码看起来是这样的,每个方法都会在gui中执行一次更改,但最终结果当然是由最后一个方法给出的: public void updateGui() { Platform.runLater(() -> { doFirstStuff(); doSecondStuff(); doThirdStuff(); }); } 如果在每
public void updateGui()
{
Platform.runLater(() -> {
doFirstStuff();
doSecondStuff();
doThirdStuff();
});
}
如果在每个方法的执行之间有一点延迟1、2或3秒,让用户有时间查看应用程序中发生了什么,那就太好了
我的尝试是:
Thread.sleep(1000);
在每次方法调用之后,但是由于线程是JavaFX应用程序线程,因此结果非常糟糕
我现在想到的另一个解决方案是:
在另一个线程中使用如下Runnable执行每个方法:
() -> {
Platform.runLater(() -> {
doFirstStuff();
});
Thread.sleep(1000);
});
在updateGui中,在newSingleThreadExecutor中提交任务,并等待每个任务的终止。但我不知道,这似乎不是个好办法
实现目标的最佳方法是什么?最简单的方法就是使用: 我在这里假设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();
}
但我认为对于这样的用例,时间线或动画API的其他部分更干净,使用的资源更少,因为它们不会创建新线程。最简单的方法就是使用: 我在这里假设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();
}
但我认为对于这样的用例,时间线或动画API的其他部分更干净,使用的资源更少,因为它们不创建新线程。这是如何工作的Platform.runLatertimeline::play;}'第一次看到它。@GoXr3Plus它是一个。它相当于Platform.runLater->timeline.play。由于timeline.play的签名没有参数,因此没有返回值与Runnable中抽象方法的签名相同。您只需传递一个方法引用来代替Runnable.run的实现即可。谢谢!正是我需要的!我尝试了这两种方法,甚至尝试了我的newSingleThreadExecutor解决方案,对于我来说效果都很好,但我想时间线方法是解决此类问题的最佳方法。是的,我正在从后台线程调用updateGui,也许我应该指定,对不起。最后一件事:为什么在关键帧和时间轴上使用最终修改器?最终修改器不是必需的。时间线和关键帧是在一个线程上创建的,然后从另一个线程访问,因此以线程安全的方式完成所有操作非常重要。关键帧是不可变的,因此如果强制创建的引用为最终引用,则可以确保没有任何更改,并且对时间轴的唯一访问是通过构造器,构造器实际上是原子的。用final修改这些并不能保证我以后不会修改时间线的属性,但这是一个很好的意图声明。这是如何工作的?”Platform.runLatertimeline::play;}'第一次看到它。@GoXr3Plus它是一个。它相当于Platform.runLater->timeline.play。由于timeline.play的签名没有参数,因此没有返回值与Runnable中抽象方法的签名相同。您只需传递一个方法引用来代替Runnable.run的实现即可。谢谢!正是我需要的!我尝试了这两种方法,甚至尝试了我的newSingleThreadExecutor解决方案,对于我来说效果都很好,但我想时间线方法是解决此类问题的最佳方法。是的,我正在从后台线程调用updateGui,也许我应该指定,对不起。最后一件事:为什么在关键帧和时间轴上使用最终修改器?最终修改器不是必需的。时间线和关键帧是在一个线程上创建的,然后从另一个线程访问,因此以线程安全的方式完成所有操作非常重要。关键帧是不可变的,因此如果强制创建的引用为最终引用,则可以确保没有任何更改,并且对时间轴的唯一访问是通过构造器,构造器实际上是原子的。用final修改这些并不能保证我以后不会修改时间线的属性,但这是一个很好的意图声明。