Skip to content

Instantly share code, notes, and snippets.

@manuel-mauky
Created May 31, 2015 18:44
Show Gist options
  • Save manuel-mauky/011e9ed4433f9eb791a8 to your computer and use it in GitHub Desktop.
Save manuel-mauky/011e9ed4433f9eb791a8 to your computer and use it in GitHub Desktop.
Recursive DataModel for JavaFX TreeView/TreeTableView

A TreeItem implementation for JavaFX TreeView/TreeTableView that can be used to display recursive data structures.

This file is taken from one of my toy-projects. A more detailed explanation can be found in my blog

import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.control.TreeItem;
import javafx.util.Callback;
import java.util.List;
import java.util.stream.Collectors;
public class RecursiveTreeItem<T> extends TreeItem<T> {
private Callback<T, ObservableList<T>> childrenFactory;
public RecursiveTreeItem(Callback<T, ObservableList<T>> func){
this(null, func);
}
public RecursiveTreeItem(final T value, Callback<T, ObservableList<T>> func){
this(value, (Node) null, func);
}
public RecursiveTreeItem(final T value, Node graphic, Callback<T, ObservableList<T>> func){
super(value, graphic);
this.childrenFactory = func;
if(value != null) {
addChildrenListener(value);
}
valueProperty().addListener((obs, oldValue, newValue)->{
if(newValue != null){
addChildrenListener(newValue);
}
});
}
private void addChildrenListener(T value){
final ObservableList<T> children = childrenFactory.call(value);
children.forEach(child -> RecursiveTreeItem.this.getChildren().add(new RecursiveTreeItem<>(child, getGraphic(), childrenFactory)));
children.addListener((ListChangeListener<T>) change -> {
while(change.next()){
if(change.wasAdded()){
change.getAddedSubList().forEach(t-> RecursiveTreeItem.this.getChildren().add(new RecursiveTreeItem<>(t, getGraphic(), childrenFactory)));
}
if(change.wasRemoved()){
change.getRemoved().forEach(t->{
final List<TreeItem<T>> itemsToRemove = RecursiveTreeItem.this.getChildren().stream().filter(treeItem -> treeItem.getValue().equals(t)).collect(Collectors.toList());
RecursiveTreeItem.this.getChildren().removeAll(itemsToRemove);
});
}
}
});
}
}
@MS-Tech
Copy link

MS-Tech commented Aug 15, 2017

Hello,

i use your class for the data model of a TreeTableView. I've seen you add new objects only at the end. I therefore have a problem because I also have objects, e.g. on the first index. In the observerable list, the object is in the first index, but in the tree view the object is in the last index. Can you extend your class to set an index if i add a new RecusiveTreeItem (line 47)?

Best regards
MS-Tech

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment