2014-09-24 78 views
0

我正在嘗試編寫一個內存可視化工具,它將用當前內存統計信息更新一個圖形,並在其邊上有一個數字表示。我有一個在線程中運行的更新方法,應該每秒更新一次。在GUI上沒有更新JavaFx文本字段

問題是它沒有在GUI上更新,事實上我相信代碼會在一次迭代後停止。我相信它與setText()的一些調用有關,因爲如果我將它們註釋掉,那麼至少該圖將會更新。

這裏是我的intialize法

@Override 
    public void initialize(URL arg0, ResourceBundle arg1) { 
     assert memUsage_lineChart != null : "fx:id=\"memUsage_lineChart\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_totalMem != null : "fx:id=\"text_totalMem\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_usedMem != null : "fx:id=\"text_usedMem\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_availableMem != null : "fx:id=\"text_availableMem\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_percentageUsed != null : "fx:id=\"text_percentageUsed\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_totalRuntime != null : "fx:id=\"text_totalRuntime\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_threadsUsed != null : "fx:id=\"text_threadsUsed\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_version != null : "fx:id=\"text_version\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_timeAtMaxMem != null : "fx:id=\"text_timeAtMaxMem\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_maxMemReached != null : "fx:id=\"text_maxMemReached\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_timeOfLastAssociation != null : "fx:id=\"text_timeOfLastAssociation\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert text_something != null : "fx:id=\"text_totalRuntime\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert lineChart_yAxis != null : "fx:id=\"lineChart_yAxis\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 
     assert lineChart_xAxis != null : "fx:id=\"lineChart_xAxis\" was not injected: check your FXML file 'MemoryVisualization.fxml'."; 

     runtime = 0L; 


     //Initializing the ArrayLists<> that will contain the series of data for each possible graph 
     memData = new ArrayList<XYChart.Series<Number,Number>>();  

     //Setting the Y-axis of the chart to change according to incoming data. 
     memUsage_lineChart.getYAxis().setAutoRanging(true); 

     //Initializes the data arrays and series for the charts 
     XYChart.Series<Number, Number> series_sec = new XYChart.Series<Number,Number>(); 
     memUsage_lineChart.getData().add(series_sec); 
     memData.add(series_sec); 

     //Creates a thread that continuously runs and adds data points to the displays 
     ScheduledExecutorService ses = Executors.newScheduledThreadPool(1); 
     ses.scheduleWithFixedDelay(new Runnable() { 
      @Override 
      public void run() { 
       runtime += 1000; 
       updateData(); 
       try { 
        Thread.sleep(500); 
        } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }, 0, 500, TimeUnit.MILLISECONDS); 

    }/*END OF INSTANTIATION*/ 

這裏是我的了updateData()方法

public void updateData() 
{ 
    //Gathers the runtime memory data from the system 
    long maxFreeMemory = Runtime.getRuntime().maxMemory(); 
    long usableFreeMemory= Runtime.getRuntime().maxMemory() 
      -Runtime.getRuntime().totalMemory() 
      +Runtime.getRuntime().freeMemory(); 
    double usedPercent=(double)(Runtime.getRuntime().totalMemory() 
      -Runtime.getRuntime().freeMemory())/Runtime.getRuntime().maxMemory(); 
    long usedMemory = (long)(usedPercent*maxFreeMemory); 
    maxFreeMemory /= 1000000; 
    usableFreeMemory /= 1000000; 
    usedMemory /= 1000000; 
    usedPercent *= 100; 
    DecimalFormat df = new DecimalFormat("0.00"); 

    //Set the text values for the runtime statistics 
    text_totalMem.textProperty().set(String.valueOf(maxFreeMemory)); 
    text_usedMem.textProperty().set(String.valueOf(usedMemory)); 
    text_availableMem.textProperty().set(String.valueOf(usableFreeMemory)); 
    text_percentageUsed.textProperty().set(df.format(usedPercent)+" %"); 
    text_totalRuntime.textProperty().set((runtime/3600000)+":"+String.format("%02d",((runtime/60000)%60))+":"+String.format("%02d",((runtime%60000)/1000))); 
    text_threadsUsed.textProperty().set(String.valueOf(ManagementFactory.getThreadMXBean().getThreadCount())); 

    //Updates the axes of the real-time graphs/charts 
    if(runtime >= 120000 && (runtime % 12000) == 0) 
    { 
     lineChart_xAxis.setLowerBound(lineChart_xAxis.getLowerBound()+12); 
     lineChart_xAxis.setUpperBound(lineChart_xAxis.getUpperBound()+12); 

     for(int i=0; i<12; i++) 
      memData.get(0).getData().remove(0); 
    } 

    //Adds the data to the series to be placed on to the graphs/charts 
    memData.get(0).getData().add(new XYChart.Data<Number,Number>(runtime/1000,usedMemory)); 
} 

有我的GUI卡住的原因;以及當這是不會更新文本字段/圖跑?我知道一個事實,即線程運行至少一次迭代,因爲當GUI彈出時文本字段不爲0(如初始化)。

回答

3

使用Platform.runLater()在FX應用程序線程上執行updateData()方法。 (此外,我認爲Thread.sleep(...)是多餘的,因爲您使用的是預定的執行程序。)

ses.scheduleWithFixedDelay(new Runnable() { 
     @Override 
     public void run() { 
      runtime += 1000; 
      Platform.runLater(() -> updateData()); 
     } 
    }, 0, 500, TimeUnit.MILLISECONDS); 
+0

是的,這工作!謝謝! – 2014-09-24 17:28:23