TreeTableView
использует rowFactory
для создания TreeTableRow
с.Через некоторое время он присваивает TreeItem
TreeTableRow
.Это может произойти снова с разными TreeItem
s для той же строки.По этой причине вам нужно обрабатывать изменения, которые можно сделать, добавив ChangeHandler
к свойству TreeTableRow.treeItem
.Если для строки назначен новый TreeItem
, вы можете проверить наличие узлов верхнего уровня, проверив дочерние элементы (невидимого) корневого элемента для элемента строки.
Я предпочитаю подход, который не требуетпоиск в списке детей, хотяМожно сравнить родительский элемент элемента с корнем.
public static class Item {
private final String value1;
private final String value2;
public Item(String value1, String value2) {
this.value1 = value1;
this.value2 = value2;
}
public String getValue1() {
return value1;
}
public String getValue2() {
return value2;
}
}
@Override
public void start(Stage primaryStage) {
final TreeItem<Item> root = new TreeItem<>(null);
TreeTableView<Item> ttv = new TreeTableView<>(root);
ttv.setShowRoot(false);
TreeTableColumn<Item, String> column1 = new TreeTableColumn<>();
column1.setCellValueFactory(new TreeItemPropertyValueFactory<>("value1"));
TreeTableColumn<Item, String> column2 = new TreeTableColumn<>();
column2.setCellValueFactory(new TreeItemPropertyValueFactory<>("value2"));
ttv.getColumns().addAll(column1, column2);
final PseudoClass topNode = PseudoClass.getPseudoClass("top-node");
ttv.setRowFactory(t -> {
final TreeTableRow<Item> row = new TreeTableRow<>();
// every time the TreeItem changes, check, if the new item is a
// child of the root and set the pseudoclass accordingly
row.treeItemProperty().addListener((o, oldValue, newValue) -> {
boolean tn = false;
if (newValue != null) {
tn = newValue.getParent() == root;
}
row.pseudoClassStateChanged(topNode, tn);
});
return row;
});
// fill tree structure
TreeItem<Item> c1 = new TreeItem<>(new Item("category 1", null));
c1.getChildren().addAll(
new TreeItem<>(new Item("sub1.1", "foo")),
new TreeItem<>(new Item("sub1.2", "bar")));
TreeItem<Item> c2 = new TreeItem<>(new Item("category 2", null));
c2.getChildren().addAll(
new TreeItem<>(new Item("sub2.1", "answer")),
new TreeItem<>(new Item("sub2.2", "42")));
root.getChildren().addAll(c1, c2);
Scene scene = new Scene(ttv);
scene.getStylesheets().add("style.css");
primaryStage.setScene(scene);
primaryStage.show();
}
style.css
.tree-table-row-cell:top-node {
-fx-background: orange;
}
Перемещение изображений влево также будетбудь милым.
Обычно вы делаете это из пользовательского TreeTableCell
, возвращаемого TreeTableColumn.cellFactory
.В зависимости от поведения, которое вы хотите реализовать, может быть достаточно установки fitWidth
/ fitHeight
, но в других случаях может потребоваться динамическое изменение этих значений на основе размера ячейки.