限制javafx gui更新

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

我一直在考虑如何最好地实现限制算法。

  • 是否最好有一个单独的GUIUpdater线程来检查例如新对象的阻塞队列,然后睡眠例如30ms然后再次检查,在无限循环中? 在这种情况下,阻塞队列是否是最佳数据结构? 请注意我只需要最新的数据对象,blockingQueue是一个FIFO队列,我似乎无法选择最新的条目。
  • 或者 – 如果nanoTime-startTime> 30ms,只需用Platform.RunLater更新GUI会更好吗? 在这种情况下,我不需要单独的线程来执行Platform.RunLater调用。 但是 – 如果在30ms未通过时收到更新,然后在一段时间内未收到任何更新,则最后一次更新将不会显示在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保存用于更新Label的当前值。 计数不断递增并更新AtomicLong ,但只调用Platform.runLater(...)如果它的当前值为-1。 Platform.runLater(...)使用AtomicLong的当前值更新Label ,并将AtomicLong翻转回-1,表示它已准备好进行新的更新。

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