当前位置: 首页 > 面试题库 >

节流JavaFX GUI更新

子车俊材
2023-03-14
问题内容

我随机地以高频率接收数据对象,并且需要使用这些对象来更新JavaFX
GUI。但是,我不想用大量可运行对象填充javafx事件队列(我使用Platform.RunLater)。

我一直在思考如何最好地实现节流算法。

  • 最好有一个单独的GUIUpdater线程来检查例如新对象的阻塞队列,然后在无限循环中例如休眠30ms然后再次检查吗?在这种情况下,阻塞队列是否是最佳数据结构?请注意,我只需要最新的数据对象,blockingQueue是FIFO队列,我似乎无法只选择最新的条目。
  • 或者-如果nanoTime-startTime> 30ms,仅使用Platform.RunLater更新GUI会更好吗?在那种情况下,我不需要单独的线程来执行Platform.RunLater调用。但是-如果在30毫秒后仍未收到更新,并且一段时间内未收到任何更新,则最后的更新将不会显示在GUI中。

关于如何设计JavaFX Platform.RunLater GUI更新的节流算法的简短建议?


问题答案:

这是Task类中用于实现该updateMessage(...)方法以及其他类似方法的惯用法。它提供了一个很好的,健壮的解决方案,可以避免淹没FX应用程序线程:

import java.util.concurrent.atomic.AtomicLong;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ThrottlingCounter extends Application {

    @Override
    public void start(Stage primaryStage) {
        final AtomicLong counter = new AtomicLong(-1);
        final Label label = new Label();
        final Thread countThread = new Thread(new Runnable() {
            @Override
            public void run() {
                long count = 0 ;
                while (true) {
                    count++ ;
                    if (counter.getAndSet(count) == -1) {
                        updateUI(counter, label);
                    }
                }
            }
        });
        countThread.setDaemon(true);
        countThread.start();

        VBox root = new VBox();
        root.getChildren().add(label);
        root.setPadding(new Insets(5));
        root.setAlignment(Pos.CENTER);

        Scene scene = new Scene(root, 150, 100);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void updateUI(final AtomicLong counter,
            final Label label) {
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                final String msg = String.format("Count: %,d", counter.getAndSet(-1));
                label.setText(msg);
            }
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}

AtomicLong保持当前值被用来更新标签。计数会不断递增和更新AtomicLong,但仅Platform.runLater(...)在当前值是-1
时才安排呼叫。该Platform.runLater(...)更新Label从当前值AtomicLong和翻转AtomicLong回-1,表明它已经准备好了新的更新。

这样做的作用是Platform.runLater(...)在FX Application
Thread准备好处理它们时安排新的调用。没有可能需要调整的硬编码时间间隔。



 类似资料:
  • 我目前正在做一个项目,在这个项目中,我将时间转换为基数10时间(本质上,它最终会显示已经过去的一天的百分比。例如:中午12:00将显示为基数10时间的50.00)。目前,我知道我的算法是正确的,因为如果我把它打印到控制台,它会正确地打印出来,但是由于某种原因,我无法显示我的图形用户界面。如果我删除了试图不断更新GUI以显示正确数字的部分,GUI显示良好,但没有数字。我的代码如下: 有人知道我将如何

  • 我正在工作的一个fpga实现deflate或gzip解压。我需要首先理解压缩数据流的格式,然后才能进行一些编码。 我阅读文档,但我总是在树上看到关于霍夫曼编码和阅读,

  • 我使用JavaFXSceneBuilder/FXML设计了一个场景,我想创建该场景的多个实例,但每个场景都有不同的行为。有没有办法动态更改场景/FXML的控制器? 我想要的是设计一个场景并重用它,但是每个实例有不同的行为。 目前我正在加载FXML及其控制器,如下所示:

  • 本文向大家介绍system.reactive 节流,包括了system.reactive 节流的使用技巧和注意事项,需要的朋友参考一下 示例 假设您需要实现一个自动搜索框,但是搜索操作的成本较高,例如发送Web请求或建立数据库。您可能想限制搜索的数量。 例如,用户在搜索框中输入“ C#Reactive Extensions”: 现在,我们不想在用户每次按键时都执行搜索。取而代之的是,只要用户停止输

  • 问题内容: 请解释什么是字节流和字符流。这些到底是什么意思?Microsoft Word文档是面向字节还是面向字符? 谢谢 问题答案: 流是顺序访问文件的一种方式。字节流逐字节访问文件。字节流适用于任何类型的文件,但不适用于文本文件。例如,如果文件使用unicode编码,并且一个字符用两个字节表示,则字节流将分别处理这些字节,您需要自己进行转换。 字符流将逐字符读取文件。必须为字符流提供文件的编码

  • 问题内容: 使用时是否可以轻松地限制kbps ?如果是这样的话,将不胜感激您可以指导我的任何代码示例或资源。 问题答案: 模块中有功能。如果将-function / object实现为令牌存储桶或泄漏存储桶,则将具有全局速率限制。 编辑: 仔细检查后,我发现进行全球限速并不像我想的那么容易。仅给出下载量和总大小,仅靠它们本身不足以提供与令牌桶配合使用的信息。解决该问题的一种方法是,在每个速率限制器