2012-05-15 129 views
2

我有一個Java FX 2應用程序,每秒更新數百次。 我遇到了一個問題,即標籤在幾分之一秒內部分消隱,但這種情況經常發生。 我該如何解決這個問題?JavaFX 2空白標籤刷新問題

enter image description here

+0

我的猜測是你只是淹沒JavaFX事件隊列或更新JavaFX應用程序線程的UI。您是否嘗試更新頻率較低? (例如<每秒30次)=>除非他們在慢動作相機上播放UI,否則如果每秒發生數百次,沒有人會看到更新,我認爲默認情況下JavaFX脈衝機制的上限爲60fps )。如果降低更新頻率不能解決問題,發佈一個可運行的簡短演示應用程序可能有助於獲得答案。 – jewelsea

+0

我可以嘗試調節,但不完全確定是否有簡單的方法來做到這一點。我正在使用Platform.runLater進行更新。 –

回答

1

調用Platform.runLater()數百次第二是不是一個好主意。我建議你在調用Platform.runLater()來更新UI之前一起調節數據源的輸入速度或者將數據批量批處理,這樣Platform.runLater不會每秒調用30次以上。

我提交了一個jira請求RT-21569以改進Platform.runLater調用的文檔,並考慮在底層平臺中實現一個優越的runLater事件限制系統。

Richard Bair在此forum thread中給出了用於批處理runLater事件的示例解決方案。

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拜爾從稱爲論壇話題複製:

這裏是模擬某些產生豐富的數據的長期運行線程的示例。 我發現它不適合我的喜好。如果Thread.sleep丟失,它仍然吞噬進程(也許這是我在這種情況下處理併發的方式)。我還發現,如果我把它減少到睡眠的「2」ms,那麼我就無法抓住滾動條的拇指並將它移動。我認爲這裏的問題是,在事件隊列中有一個用於按下和拖動的鼠標事件,但是在拖動事件之間,新項目被添加到列表中,導致拇指移動,並且因爲這比我的拖動事件發生得更頻繁,拇指永遠不會去我想要的地方。我認爲這是由於拇指位置根據行數處理的方式,不知道可以做些什麼,除了應用程序調節和批量添加行之外,正如我在這裏所做的那樣。

+0

我無法在該線程上找到答案......唯一的答案是創建線程的負載......並不理想。 –

+0

我將引用線程中的示例解決方案複製到我的答案中。請注意,此解決方案由Richard Bair創建,不是我。 – jewelsea