2012-12-14 144 views
2

我試圖顯示JavaFXTableView中的每個任務的進度和狀態。每個任務由一行代表TableViewJavaFX TableView未更新

enter image description here

每個任務都執行一個單獨的線程。任務可能像 - 從服務器下載文件,將文件從一個帳戶複製到另一個帳戶等。線程可能需要很長時間才能完成任務。我的應用程序還控制在隊列中執行操作的線程數。使用默認設置,它一次最多可以運行5個線程。

我的問題是 - 我的TableView未顯示更新的狀態和進度。我必須點擊列標題才能刷新TableView。如何使TableView更新爲aromatically?在後臺,如果我運行一個線程,在特定的時間間隔後自動觸發以刷新TableView,使我的UI凍結。

該示例沒有顯示我在我的應用程序中究竟做了什麼,但我試圖證明我面臨的是什麼問題。當你運行該程序時,你會看到兩個列1.名稱和2.進度的TableView。在啓動時,每行的名稱將會是「之前」,而您將看到進度條正在運行。我在更新單元格值時添加了1秒的延遲並停止進度條。

import java.util.logging.Level; 
import java.util.logging.Logger; 
import javafx.application.Application; 
import javafx.beans.property.DoubleProperty; 
import javafx.beans.property.SimpleDoubleProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.control.cell.ProgressBarTableCell; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.layout.StackPane; 
import javafx.scene.layout.StackPaneBuilder; 
import javafx.stage.Stage; 

public class UpdateTableView extends Application { 

    private TableView<Person> personTable = new TableView<>(); 
    private TableColumn colName = new TableColumn<>("Name"); 
    private TableColumn colProgressBar = new TableColumn("Progress Bar"); 

    @Override 
    public void start(Stage primaryStage) { 
     showDialog(primaryStage); 

     colName.setCellValueFactory(new PropertyValueFactory("name")); 
     colProgressBar.setCellValueFactory(new PropertyValueFactory("progressBar")); // "name" here is for just to render the column 
     colProgressBar.setCellFactory(ProgressBarTableCell.forTableColumn()); 
     personTable.getColumns().addAll(colName, colProgressBar); 

     for (int i = 0; i < 10; i++) { 
      Person person = new Person(); 
      person.setProgressBar(-1.0); 
      person.setName("Before" + i); 
      personTable.getItems().add(person); 
     } 


     Thread threadAction1 = new Thread() { 
      public void run() { 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(UpdateTableView.class.getName()).log(Level.SEVERE, null, ex); 
       } 
       ObservableList<Person> items = personTable.getItems(); 
       for (int i = 0; i < items.size(); i++) { 
        Person person = items.get(i); 
        person.setName("After" + i); 
        person.setProgressBar(0.0); 
       } 
      } 
     }; 
     threadAction1.start(); 
    } 

    public void showDialog(Stage primaryStage) { 
     try { 
      StackPane root = StackPaneBuilder.create().children(personTable).build(); 
      primaryStage.setScene(new Scene(root, 300, 250)); 
      primaryStage.show(); 
     } catch (Exception ex) { 
      System.out.println("Exception caught while showing dialog" + ex.getMessage()); 
     } 
    } 

    public static class Person { 

     private StringProperty name; 

     public void setName(String name) { 
      this.name = new SimpleStringProperty(name); 
     } 
     private DoubleProperty progressBar; 

     private Person() { 
     } 

     public double getProgressBar() { 
      return progressBar.get(); 
     } 

     public void setProgressBar(double surname) { 
      this.progressBar = new SimpleDoubleProperty(surname); 
     } 

     public Person(String name, double surname) { 
      this.name = new SimpleStringProperty(name); 
      this.progressBar = new SimpleDoubleProperty(surname); 

     } 

     public String getName() { 
      return name.get(); 
     } 

     public StringProperty nameProperty() { 
      return name; 
     } 

     public DoubleProperty progressBarProperty() { 
      return progressBar; 
     } 
    } 

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

回答

4

你應該有更新您的Person類,如下所示:

public static class Person { 

    private StringProperty name; 
    private DoubleProperty progressBar; 

    private Person() { 
     name = new SimpleStringProperty(); 
     progressBar = new SimpleDoubleProperty(); 
    } 

    public Person(String name, double surname) { 
     this.name = new SimpleStringProperty(name); 
     this.progressBar = new SimpleDoubleProperty(surname); 
    } 

    public void setName(String name) { 
     this.name.set(name); 
    } 

    public double getProgressBar() { 
     return progressBar.get(); 
    } 

    public void setProgressBar(double surname) { 
     this.progressBar.set(surname); 
    } 

    public String getName() { 
     return name.get(); 
    } 

    public StringProperty nameProperty() { 
     return name; 
    } 

    public DoubleProperty progressBarProperty() { 
     return progressBar; 
    } 
} 

setter方法要創建的每個時間name & progressbar新的對象,以便TableView是沒有得到更新。