本文介绍了JavaFX 2空白标签刷新问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java FX 2应用程序,它每秒更新数百次.我遇到一个问题,其中标签被部分消隐了不到一秒钟的时间,但是这种情况经常发生.我该如何解决?

I have a Java FX 2 app which is updating hundreds of times a second. I'm getting a problem where the labels are partially blanked for a fraction of a second but this happens fairly often.How do I fix this?

推荐答案

调用 Platform.runLater()每秒数百次都不是一个好主意.我建议您在调用Platform.runLater()来更新UI之前,先限制数据源的输入速度或将数据批处理在一起,以确保每秒不调用Platform.runLater> 30次.

Calling Platform.runLater() hundreds of times a second is not a good idea. I advise you throttle the input speed of your data source or batch your data together before invoking Platform.runLater() to update your UI, such that Platform.runLater isn't invoked > 30 times a second.

我提交了一个jira请求 RT-21569 ,以改进关于Platform.runLater调用,并考虑在基础平台中实现高级runLater事件限制系统.

I filed a jira request RT-21569 to improve the documentation on the Platform.runLater call and consider implementing a superior runLater event throttling system in the underlying platform.

Richard Bair在此论坛线程中给出了批处理runLater事件的示例解决方案. .

A sample solution for batching runLater events is given by Richard Bair in this forum thread.

import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.stage.Stage;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 *
 */
public class BackgroundLoadingApp extends Application {

    private ListView<String> listView;

    private List<String> pendingItems;

    private Semaphore lock = new Semaphore(1);

    protected void addItem(String item) throws InterruptedException {
        if (Platform.isFxApplicationThread()) {
            listView.getItems().add(item);
        } else {
            // It might be that the background thread
            // will update this title quite frequently, and we need
            // to throttle the updates so as not to completely clobber
            // the event dispatching system.
            lock.acquire();
            if (pendingItems == null) {
                pendingItems = new LinkedList<String>();
                pendingItems.add(item);
                Platform.runLater(new Runnable() {
                    @Override public void run() {
                        try {
                            lock.acquire();
                            listView.getItems().addAll(pendingItems);
                            pendingItems = null;
                        } catch (InterruptedException ex) {
                            ex.printStackTrace();
                        } finally {
                            lock.release();
                        }
                    }
                });
            } else {
                pendingItems.add(item);
            }
            lock.release();
        }
    }

    /**
     * The main entry point for all JavaFX applications.
     * The start method is called after the init method has returned,
     * and after the system is ready for the application to begin running.
     * <p/>
     * <p>
     * NOTE: This method is called on the JavaFX Application Thread.
     * </p>
     *
     * @param primaryStage the primary stage for this application, onto which
     *                     the application scene can be set. The primary stage will be embedded in
     *                     the browser if the application was launched as an applet.
     *                     Applications may create other stages, if needed, but they will not be
     *                     primary stages and will not be embedded in the browser.
     */
    @Override public void start(Stage primaryStage) throws Exception {
        listView = new ListView<String>();
        primaryStage.setScene(new Scene(listView));
        primaryStage.show();

        // Start some background thread to load millions of rows as fast as it can. But do
        // so responsibly so as not to throttle the event thread
        Thread th = new Thread() {
            @Override public void run() {
                try {
                    for (int i=0; i<2000000; i++) {
                        addItem("Item " + i);
                        if (i % 200 == 0) {
                            Thread.sleep(20);
                        }
                    }
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        };
        th.setDaemon(true);
        th.start();
    }

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

Richard Bair的评论来自引用的论坛主题:

Comments by Richard Bair copied from the referred forum thread:

这篇关于JavaFX 2空白标签刷新问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 00:36