请求JavaFX线程调用一些代码而不使用Platform.runLater
在我正在制作的应用程序中,我希望所有的事情都在一个线程上完成。我想介绍一些异步的网络IO。我想我应该把它放在一个线程上,以减少复杂性,并且只使用一个通道/选择器 主JavaFX线程是否有办法定期(或在其逻辑结束时)调用代码块。在这种情况下,我更希望它经常这样做,以使应用程序始终保持最新 我试着四处寻找如何做到这一点,但我没有运气 如果我要用这个做一些ASCII艺术:请求JavaFX线程调用一些代码而不使用Platform.runLater,java,multithreading,networking,javafx,Java,Multithreading,Networking,Javafx,在我正在制作的应用程序中,我希望所有的事情都在一个线程上完成。我想介绍一些异步的网络IO。我想我应该把它放在一个线程上,以减少复杂性,并且只使用一个通道/选择器 主JavaFX线程是否有办法定期(或在其逻辑结束时)调用代码块。在这种情况下,我更希望它经常这样做,以使应用程序始终保持最新 我试着四处寻找如何做到这一点,但我没有运气 如果我要用这个做一些ASCII艺术: | Is there a gap here I can run the code in? |
| Is there a gap here I can run the code in?
| V
|[JavaFX thread]--------------o --------------o --------------o
| ^
| Here all the UI work is done and it pauses before starting again
我不知道JavaFX线程是否就是这样工作的。我想,在完成所有图形更新和逻辑之后,它会在某个地方暂停并调用任何Runnable,由Platform.runLater
执行。这里的问题是我不想一直用新的Runnables来垃圾邮件,我猜这是一个坏习惯
理想情况下,我希望使用它,以便主JavaFX线程执行其所有逻辑,然后它轮询来自网络连接的任何输入。即使用户什么也不做(这意味着我不能依靠用户输入事件来触发套接字读取),也应该运行该命令
有办法做到这一点吗
注意:从套接字接收的数据将与JavaFX模块中的内容交互,因此有更多的理由将其保留在主JavaFX线程上。您可以这样做,但请注意,当处理时间过长时,它可能会阻塞您的UI。你可以滥用或为此,或者你可以使用一个方便的包装 暂停转换
PauseTransition pt = new PauseTransition(Duration.millis(500));
pt.setOnFinished(ae -> {
// do your work here, it runs on the JavaFX application thread
});
SequentialTransition seq = new SequentialTransition(pt);
seq.setCycleCount(Animation.INDEFINITE);
seq.play();
时间线
Timeline timeline = new Timeline(new KeyFrame(
Duration.millis(500),
ae -> {
// do your work here, it runs on the JavaFX application thread
}));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
ReactFX
FxTimer.runPeriodically(
Duration.ofMillis(500),
() -> {
// do your work here, it runs on the JavaFX application thread
});
看看AnimationTimer类。它完全符合您的要求。我不能使用您的最佳示例,它拒绝在将System.out.println子绑定到PauseTransition时运行,但ReactFX似乎正在执行此任务。@Water您是对的。我更新了代码示例,将
暂停转换
包装在顺序转换
中。以前的问题是,代码不是在每个周期后执行的,而是在整个动画结束后执行的,这从来都不是。我还添加了时间线
示例。