请求JavaFX线程在不使用Platform.runLater的情况下调用某些代码

时间:2015-03-06 22:59:12

标签: java multithreading networking javafx

在我正在制作的应用程序中,我想在一个线程上完成所有操作。我想介绍一些异步的网络IO。我想我会将它保留在一个线程上,以减少并发症,只需使用通道/选择器。

主JavaFX线程是否有一种方法可以定期(或在其逻辑结束时)调用一段代码。在这种情况下,我更喜欢经常这样做,以便始终保持应用程序的最新状态。

我试过四处寻找如何做到这一点,但我没有运气。

如果我要做一些ASCII艺术:

|                    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线程上。

2 个答案:

答案 0 :(得分:1)

您可以这样做,但请注意,当处理时间过长时,它可能会阻止您的UI。您可以滥用TimelinePauseTransition,也可以使用ReactFX中的方便包装。

<强> PauseTransition

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
        });

答案 1 :(得分:1)

查看AnimationTimer类。它完全符合您的要求。