- Loading...
As mentioned, the intention is to be able to define a TreeTableView instance with as little new knowledge over and above TableView and TreeView. Here is a simple code example for creating a static TreeTableView instance (note that it is a particularly poor example from a data point of view, but it captures the general approach nonetheless):
final TreeItem<String> root = new TreeItem<String>("Root node");
final TreeItem<String> childNode1 = new TreeItem<String>("Child Node 1");
final TreeItem<String> childNode2 = new TreeItem<String>("Child Node 2");
final TreeItem<String> childNode3 = new TreeItem<String>("Child Node 3");
root.setExpanded(true);
root.getChildren().setAll(childNode1, childNode2, childNode3);
TreeTableColumn<String, String> column = new TreeTableColumn<String, String>("Column");
column.setCellValueFactory(new Callback<CellDataFeatures<String, String>, ObservableValue<String>>() {
@Override public ObservableValue<String> call(CellDataFeatures<String, String> p) {
return new ReadOnlyStringWrapper(p.getValue().getValue());
}
});
final TreeTableView<String> treeTableView = new TreeTableView<String>(root);
treeTableView.getColumns().add(column);
A slightly more complete code example is shown below, which builds a TreeTableView instance that will dynamically populate the tree on demand with the content of the users filesystem.
private TreeTableView buildFileBrowserTreeTableView() {
TreeItem<File> root = createNode(new File("/"));
root.setExpanded(true);
final TreeTableView<File> treeTableView = new TreeTableView<File>();
treeTableView.setShowRoot(true);
treeTableView.setRoot(root);
// --- name column
TreeTableColumn<File, String> nameColumn = new TreeTableColumn<File, String>("Name");
nameColumn.setPrefWidth(300);
nameColumn.setCellValueFactory(new Callback<CellDataFeatures<File, String>, ObservableValue<String>>() {
@Override public ObservableValue<String> call(CellDataFeatures<File, String> p) {
File f = p.getValue().getValue();
String text = f.getParentFile() == null ? "/" : f.getName();
return new ReadOnlyObjectWrapper<String>(text);
}
});
// --- size column
TreeTableColumn<File, File> sizeColumn = new TreeTableColumn<File, File>("Size");
sizeColumn.setPrefWidth(100);
sizeColumn.setCellValueFactory(new Callback<CellDataFeatures<File, File>, ObservableValue<File>>() {
@Override public ObservableValue<File> call(CellDataFeatures<File, File> p) {
return new ReadOnlyObjectWrapper<File>(p.getValue().getValue());
}
});
sizeColumn.setCellFactory(new Callback<TreeTableColumn<File, File>, TreeTableCell<File, File>>() {
@Override public TreeTableCell<File, File> call(final TreeTableColumn<File, File> p) {
return new TreeTableCell<File, File>() {
@Override protected void updateItem(File item, boolean empty) {
super.updateItem(item, empty);
TreeTableView treeTable = p.getTreeTableView();
// if the File is a directory, it has no size...
if (getIndex() >= treeTable.impl_getTreeItemCount()) {
setText(null);
} else {
TreeItem<File> treeItem = treeTable.getTreeItem(getIndex());
if (item == null || empty || treeItem == null ||
treeItem.getValue() == null || treeItem.getValue().isDirectory()) {
setText(null);
} else {
setText(nf.format(item.length()) + " KB");
}
}
}
};
}
});
sizeColumn.setComparator(new Comparator<File>() {
@Override public int compare(File f1, File f2) {
long s1 = f1.isDirectory() ? 0 : f1.length();
long s2 = f2.isDirectory() ? 0 : f2.length();
long result = s1 - s2;
if (result < 0) {
return -1;
} else if (result == 0) {
return 0;
} else {
return 1;
}
}
});
// --- modified column
TreeTableColumn<File, Date> lastModifiedColumn = new TreeTableColumn<File, Date>("Last Modified");
lastModifiedColumn.setPrefWidth(130);
lastModifiedColumn.setCellValueFactory(new Callback<CellDataFeatures<File, Date>, ObservableValue<Date>>() {
@Override public ObservableValue<Date> call(CellDataFeatures<File, Date> p) {
return new ReadOnlyObjectWrapper<Date>(new Date(p.getValue().getValue().lastModified()));
}
});
lastModifiedColumn.setCellFactory(new Callback<TreeTableColumn<File, Date>, TreeTableCell<File, Date>>() {
@Override public TreeTableCell<File, Date> call(TreeTableColumn<File, Date> p) {
return new TreeTableCell<File, Date>() {
@Override protected void updateItem(Date item, boolean empty) {
super.updateItem(item, empty);
if (item == null || empty) {
setText(null);
} else {
setText(df.format(item));
}
}
};
}
});
treeTableView.getColumns().setAll(nameColumn, sizeColumn, lastModifiedColumn);
return treeTableView;
}
private TreeItem<File> createNode(final File f) {
final TreeItem<File> node = new TreeItem<File>(f) {
private boolean isLeaf;
private boolean isFirstTimeChildren = true;
private boolean isFirstTimeLeaf = true;
@Override public ObservableList<TreeItem<File>> getChildren() {
if (isFirstTimeChildren) {
isFirstTimeChildren = false;
super.getChildren().setAll(buildChildren(this));
}
return super.getChildren();
}
@Override public boolean isLeaf() {
if (isFirstTimeLeaf) {
isFirstTimeLeaf = false;
File f = (File) getValue();
isLeaf = f.isFile();
}
return isLeaf;
}
};
return node;
}
private ObservableList<TreeItem<File>> buildChildren(TreeItem<File> TreeItem) {
File f = (File) TreeItem.getValue();
if (f != null && f.isDirectory()) {
File[] files = f.listFiles();
if (files != null) {
ObservableList<TreeItem<File>> children = FXCollections.observableArrayList();
for (File childFile : files) {
children.add(createNode(childFile));
}
return children;
}
}
return FXCollections.emptyObservableList();
}