2016-11-10 49 views
1

我正在寫應用程序,測量在任務上花費的時間。我有TableTreeView包含項目及其任務的詳細信息。如何更新TreeTableView數據?

這是它的外觀:TableTreeViewImage

我想是讓duration`s列任務運行時更新其值。項目持續時間也應該更新。

這是我的模型:

public abstract class SimpleTask{ 
    abstract Duration getDuration(); 
} 

public class Task extends SimpleTask{ 
    Duration duration; 

    @Override 
    public Duration getDuration(){ 
     return duration; 
    } 

    public start(){ 
     //update duration value every second; 
    } 

} 


public class Project extends SimpleTask{ 
    List<Task> tasks; 

    @Override 
    public Duration getDuration(){ 
     return tasks.stream() 
       .map(Task::getDuration) 
       .reduce(Duration.ZERO,Duration::plus); 
     } 

我試圖綁定方法getDuration()持續時間列,但隨後TableTreeView需要刷新此列更新值。

durat.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<SimpleTask, Duration>, ObservableValue<Duration>>() { 
      @Override 
      public ObservableValue<Duration> call(TreeTableColumn.CellDataFeatures<GeneralTask, Duration> SimpleTaskDurationCellDataFeatures) { 
       return new SimpleObjectProperty<Duration>(SimpleTaskDurationCellDataFeatures.getValue().getValue().getDuration()); 
      } 
     }); 

當任務運行時,如何讓duration列更新其值?

回答

0

只需將ReadOnlyObjectProperty<Duration>添加到SimpleTask並使用它代替由cellValueFactory創建的新SimpleObjectProperty。否則,你就需要「手動觸發」更新(開始使用JavaFX 8u60提供)每次的持續時間被修改時使用TableView.refresh表:

public abstract class SimpleTask { 

    public abstract Duration getDuration(); 

    public abstract ReadOnlyObjectProperty<Duration> durationProperty(); 
} 

public class Task extends SimpleTask { 

    private final ReadOnlyObjectWrapper<Duration> duration = new ReadOnlyObjectWrapper<>(); 

    @Override 
    public Duration getDuration() { 
     return duration.get(); 
    } 

    public ReadOnlyObjectProperty<Duration> durationProperty() { 
     return duration.getReadOnlyProperty(); 
    } 

    public void start() { 
     //update duration value every second using this.duration.set(newDuration); 
    } 

} 

public class Project extends SimpleTask { 

    private final ObservableList<Task> tasks; 

    private final ReadOnlyObjectWrapper<Duration> duration; 

    public Project() { 
     this.duration = new ReadOnlyObjectWrapper<>(); 
     this.tasks = FXCollections.observableArrayList(t -> new Observable[]{t.durationProperty()}); 
     this.duration.bind(Bindings.createObjectBinding(() 
       -> tasks.stream() 
       .map(Task::getDuration) 
       .reduce(Duration.ZERO, Duration::plus), 
       this.tasks)); 
    } 

    @Override 
    public Duration getDuration() { 
     return duration.get(); 
    } 

    public ReadOnlyObjectProperty<Duration> durationProperty() { 
     return duration.getReadOnlyProperty(); 
    } 

} 
durat.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<SimpleTask, Duration>, ObservableValue<Duration>>() { 
    @Override 
    public ObservableValue<Duration> call(TreeTableColumn.CellDataFeatures<SimpleTask, Duration> simpleTaskDurationCellDataFeatures) { 
     return simpleTaskDurationCellDataFeatures.getValue().getValue().durationProperty(); 
    } 
}); 

需要注意的是,你可以通過減少重複代碼將start()以外的所有成員從Task提取到另一個抽象類,並添加protected方法來訪問該屬性本身,不僅是隻讀版本,而且還用Project擴展該類。