Reputation: 1217
I have a TreeTableIView with 3 levels. I want to show Checkboxes on leafs only, while all other cells remain empty. So far, I have created 2 columns:
The first column holds the hierarchy:
TreeTableColumn<AttributeRow, String> attributeColumn = new TreeTableColumn<>("Attributes");
attributeColumn.setPrefWidth(200);
attributeColumn.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<AttributeRow, String> param) ->
new ReadOnlyStringWrapper(param.getValue().getValue().getAttributeName())
);
The second columns shall contain the CheckBoxes on leafs only:
TreeTableColumn<AttributeRow, Boolean> companyColumn = new TreeTableColumn<>(companyGroup);
companyColumn.setPrefWidth(200);
companyColumn.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(companyColumn));
companyColumn.setCellValueFactory(param -> {
if (param.getValue().getValue().getCompanyGroups() == null) {
return new SimpleBooleanProperty(true);
} else {
return new SimpleBooleanProperty(false);
}
});
This is what I want to achieve:
Is there a way to only show CheckBoxes on leafs, while the other cells are empty? Thanks!
Upvotes: 3
Views: 1369
Reputation: 82461
You can use a custom rowFactory
that checks, if the item it contains is a leaf or not and adds or removes a leaf
pseudoclass:
private static final PseudoClass LEAF = PseudoClass.getPseudoClass("leaf");
...
treeTableView.setRowFactory(view -> new TreeTableRow<BoolItem>() {
{
ChangeListener<Boolean> listener = (observable, oldValue, newValue) -> {
pseudoClassStateChanged(LEAF, newValue);
};
treeItemProperty().addListener((observable, oldItem, newItem) -> {
if (oldItem != null) {
oldItem.leafProperty().removeListener(listener);
}
if (newItem != null) {
newItem.leafProperty().addListener(listener);
listener.changed(null, null, newItem.isLeaf());
} else {
listener.changed(null, null, Boolean.FALSE);
}
});
}
});
Furthemore use a custom cellFactory
that in addition to creating the cell also assigns a style class to it that allows you to identify it as a cell that should be hidden, if it's not a leaf:
companyColumn.setCellFactory((TreeTableColumn<AttributeRow, Boolean> param) -> {
CheckBoxTreeTableCell<AttributeRow, Boolean> cell = new CheckBoxTreeTableCell<>();
cell.getStyleClass().add("hide-non-leaf");
return cell;
});
This allows you to hide the appropriate cells from a CSS stylesheet:
.tree-table-row-cell .hide-non-leaf * {
/* invisible by default */
visibility: hidden;
}
.tree-table-row-cell:leaf .hide-non-leaf * {
/* make visible, if leaf */
visibility: visible;
}
Edit: For some reason javafx seems to set the visibility of the cell inline, which overrides the CSS style. Therefore you the children of the cells are made invisible instead of the cells themselves.
Upvotes: 7