2016-11-10 5 views
1

Ich schreibe eine App, die die Zeit für Aufgaben misst. Ich habe TableTreeView, das Details des Projekts und seiner Aufgaben enthält.Wie aktualisiert man TreeTableView Daten?

Dies ist, wie es aussieht: TableTreeViewImage

Was ich will, ist duration`s Spalte zu aktualisieren ihre Werte zu machen, wenn Aufgabe ausgeführt wird. Auch die Projektdauer sollte aktualisiert werden.

Das ist mein Modell:

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); 
     } 

ich versucht habe, Dauer Spalte mit Methode getDuration() zu binden, aber dann muss TableTreeView aufgefrischt werden Werte in dieser Spalte aktualisieren.

Wie kann ich die Spalte duration aktualisieren, wenn die Task ausgeführt wird?

Antwort

0

Fügen Sie einfach ReadOnlyObjectProperty<Duration> zu SimpleTask hinzu und verwenden Sie es anstelle eines neuen SimpleObjectProperty, erstellt von cellValueFactory. sonst müssen Sie „manuell auslösen“ aktualisieren, die Tabelle mit TableView.refresh (mit javafx 8u60 verfügbarem Ausgang) jedes Mal, wenn eine Dauer geändert wird:

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(); 
    } 
}); 

Beachten Sie, dass die Code-Duplizierung reduzieren könnten durch Extrahieren aller Mitglieder außer start() von Task in eine andere abstrakte Klasse, Hinzufügen von protected Methoden, um auf die Eigenschaft selbst zuzugreifen, nicht nur die Readonly-Version und Erweiterung dieser Klasse mit Project auch.

Verwandte Themen