Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nezarjhons/870cad4c60c70370d048324d49822267 to your computer and use it in GitHub Desktop.
Save nezarjhons/870cad4c60c70370d048324d49822267 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);
});
}
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment