I have been trying to use the cell factories that are provided by the JavaFX CheckBoxTreeTableCell
, but I can't figure out how to make it work.
The Javadoc does not seem to match the implementation. For example:
public static <S,T> Callback<TreeTableColumn<S,T>,TreeTableCell<S,T>> forTreeTableColumn(Callback<Integer,ObservableValue<Boolean>> getSelectedProperty)
...
Parameters:
getSelectedProperty - A Callback that, given an object of type TreeTableColumn<S,T>, will return an ObservableValue<Boolean> that represents whether the given item is selected or not.
What does the Integer represent? Does anyone have any example code of how this is intended to be used?
Thanks,
Rob
I think you want to use forTreeTableColumn(TreeTableColumn column).
final TreeTableView<Integer> integerTreeTableView = new TreeTableView<>();
final TreeTableColumn<Integer, Boolean> column = new TreeTableColumn<>();
column.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(column));
column.setCellValueFactory(param -> {
if(param.getValue().getValue() > 5) {
return new SimpleBooleanProperty(true);
} else {
return new SimpleBooleanProperty(false);
}
});
integerTreeTableView.getColumns().add(column);
There are four methods for CheckBoxTreeTableCell.forTreeTableColumn
. All of them expect a callback, being the TreeTableColumn
of type ObservableValue<Boolean>
, or just a TreeTableColumn
of type Boolean
.
In the last case, since you already provide the column, when the updateItem
method is called for a given index to render the checkbox, its selected state is found at that position.
While on the methods with the callbacks, to find the selected state for a given index, a call
to that index is made.
This is a very simple use case of both situations. You can see how the callback use the index to go into the collection and retrieve the status:
private final ObservableList<Person> data = FXCollections.observableArrayList(
new Person("Staff",false),
new Person("John",false),
new Person("Greg",true));
@Override
public void start(Stage primaryStage) {
TreeItem<Person> rootTree = new TreeItem<>(data(0));
rootTree.setExpanded(true);
data.stream().skip(1).forEach(person->rootTree.getChildren().add(new TreeItem<>(person)));
TreeTableView<Person> table=new TreeTableView<>(rootTree);
TreeTableColumn<Person,String> columnName=new TreeTableColumn<>("Name");
columnName.setCellValueFactory(cellData -> cellData.getValue().getValue().nameProperty());
columnName.setPrefWidth(100);
TreeTableColumn<Person,Boolean> columnWeight=new TreeTableColumn<>("Overweight");
// case TreeTableColumn (uncomment to run)
// columnWeight.setCellFactory(CheckBoxTreeTableCell.forTreeTableColumn(columnWeight));
// case Callback:
columnWeight.setCellFactory(
CheckBoxTreeTableCell.forTreeTableColumn(
(Integer param) -> data.get(param).overWeightProperty()));
columnWeight.setCellValueFactory(cellData -> cellData.getValue().getValue().overWeightProperty());
columnWeight.setPrefWidth(150);
table.getColumns().addAll(columnName, columnWeight);
table.setEditable(true);
Scene scene = new Scene(table, 400, 300);
primaryStage.setScene(scene);
primaryStage.show();
}
where:
private class Person {
public Person(String name, boolean overWeight) {
this.name.set(name);
this.overWeight.set(overWeight);
}
private final StringProperty name = new SimpleStringProperty();
public String getName() {
return name.get();
}
public void setName(String value) {
name.set(value);
}
public StringProperty nameProperty() {
return name;
}
private final BooleanProperty overWeight = new SimpleBooleanProperty();
public boolean isOverWeight() {
return overWeight.get();
}
public void setOverWeight(boolean value) {
overWeight.set(value);
}
public BooleanProperty overWeightProperty() {
return overWeight;
}
}