Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
272 views
in Technique[技术] by (71.8m points)

java - Throttling javafx gui updates

I receive data objects at random times at a high frequency, and need to update the JavaFX GUI with these. However, I don't want to fill the javafx event queue with a very large number of runnables (I use Platform.RunLater).

I have been thinking of how to best implement a throttling algorithm.

  • Would it be best to have a separate GUIUpdater thread that check for example a blocking queue for new objects, and then sleeps for example for 30ms and then checks again, in an infinite loop? In that case, would a blocking queue be the optimal data structure? Please note I only need the latest data object and the blockingQueue is a FIFO queue and I can't seem to pick only the latest entry.
  • Or - would it be better to simply just update the GUI with Platform.RunLater if nanoTime-startTime > 30ms? In that case, I don't need a separate thread to perform the Platform.RunLater-call. However - if an update is received when 30ms hasn't passed, and then no updates are received for some time, the last update will not show up in the GUI.

Any suggestions on how to design a throttling algorithm for JavaFX Platform.RunLater GUI updates in a short, efficient way?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is the idiom used in the Task class for implementing the updateMessage(...) method, and other similar methods. It provides a nice, robust solution to avoid flooding the FX Application Thread:

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

The AtomicLong holds the current value to be used to update the Label. The count continually increments and updates the AtomicLong, but only schedules a call to Platform.runLater(...) if it's current value is -1. The Platform.runLater(...) updates the Label with the current value from the AtomicLong and flips the AtomicLong back to -1, indicating that it's ready for a new update.

The effect here is to schedule new calls to Platform.runLater(...) whenever the FX Application Thread is ready to handle them. There's no hard-coded time interval which could need tuning.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...