2012-12-14 146 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是没有得到更新。