Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
TreeTableView example with styled root node view.
@CHARSET "UTF-8";
.tree-table-row-cell:first-row .tree-table-cell {
-fx-text-fill: red ;
}
import java.io.File;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.Comparator;
import java.util.Date;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.css.PseudoClass;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableRow;
import javafx.scene.control.TreeTableView;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class TreeTableWithStyledRoot extends Application {
private final static NumberFormat NumberFormater = NumberFormat.getIntegerInstance();
private final static DateFormat DateFormater = DateFormat.getDateTimeInstance();
@Override
public void start(Stage primaryStage) {
TreeTableView<File> treeTableView = new TreeTableView<>();
buildFileBrowserTreeTableView(treeTableView);
final PseudoClass firstRowClass = PseudoClass.getPseudoClass("first-row");
treeTableView.setRowFactory(treeTable -> {
TreeTableRow<File> row = new TreeTableRow<File>();
row.treeItemProperty().addListener((ov, oldTreeItem, newTreeItem) ->
row.pseudoClassStateChanged(firstRowClass, newTreeItem == treeTable.getRoot()));
return row ;
});
BorderPane root = new BorderPane(treeTableView);
root.setPadding(new Insets(10));
Scene scene = new Scene(root, 640, 480);
scene.getStylesheets().add(getClass().getResource("tree-table-view.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
private void buildFileBrowserTreeTableView(TreeTableView<File> treeTableView) {
TreeItem<File> root = createNode(new File(System.getProperty("user.home")));
root.setExpanded(true);
treeTableView.setRoot(root);
// --- name column
TreeTableColumn<File, String> nameColumn = new TreeTableColumn<File, String>("Name");
nameColumn.setPrefWidth(300);
nameColumn.setCellValueFactory(
new Callback<TreeTableColumn.CellDataFeatures<File, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(TreeTableColumn.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<TreeTableColumn.CellDataFeatures<File, File>, ObservableValue<File>>() {
@Override public ObservableValue<File> call(TreeTableColumn.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<File> treeTable = p.getTreeTableView();
TreeItem<File> treeItem = treeTable.getTreeItem(getIndex());
if (item == null || empty || treeItem == null ||
treeItem.getValue() == null || treeItem.getValue().isDirectory()) {
setText(null);
} else {
setText(NumberFormater.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<TreeTableColumn.CellDataFeatures<File, Date>, ObservableValue<Date>>() {
@Override public ObservableValue<Date> call(TreeTableColumn.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(DateFormater.format(item));
}
}
};
}
});
treeTableView.getColumns().setAll(nameColumn, sizeColumn, lastModifiedColumn);
}
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();
}
public static void main(String[] args) {
launch(args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment