gpt4 book ai didi

java - 节流 javafx gui 更新

转载 作者:太空狗 更新时间:2023-10-29 22:54:45 29 4
gpt4 key购买 nike

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

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

  • 是否最好有一个单独的 GUIUpdater 线程来检查新对象的阻塞队列,然后 hibernate 30 毫秒,然后再次检查,无限循环?在那种情况下,阻塞队列会是最佳数据结构吗?请注意,我只需要最新的数据对象,而 blockingQueue 是一个 FIFO 队列,我似乎无法只选择最新的条目。
  • 或者 - 如果 nanoTime-startTime > 30 毫秒,仅使用 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,但仅在其当前值为 -1 时安排对 Platform.runLater(...) 的调用。 Platform.runLater(...) 使用 AtomicLong 的当前值更新 Label 并翻转 AtomicLong 回到 -1,表示它已准备好进行新的更新。

此处的效果是在 FX 应用程序线程准备好处理它们时安排对 Platform.runLater(...) 的新调用。没有可能需要调整的硬编码时间间隔。

关于java - 节流 javafx gui 更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23488280/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com