As James_D states in comments:
If you're using the check box just to track a set of selected rows, you could just use the table view's built-in selection functionality instead of having a check box at all.
However, if the built-in selection functionality is not appropriate for you and you do need checkbox functionality, then you either:
- Set a custom cell factory on a column, and override updateItem as in Ruslan's answer OR
- Use the built-in CheckBoxTableCell functionality.
Of the two options, I'd advise using the CheckBoxTableCell instead of creating a custom cell factory and update handler (unless, for some some reason, CheckBoxTableCell won't work for you).
There are various existing StackOverflow questions or Oracle forum questions asking how to use CheckBoxTableCell if you need more information on it:
The key parts of using a CheckBoxTableCell are to define a related boolean property in the model class that is backing your table and to link it to the relevant editable table column:
vegetarianCol.setCellValueFactory(new PropertyValueFactory<>("vegetarian"));
vegetarianCol.setCellFactory(CheckBoxTableCell.forTableColumn(vegetarianCol));
vegetarianCol.setEditable(true);
I have just copy and pasted the James_D's solution from the Oracle forum link below (this is older code, newer code should not use PropertyValueFactory):
import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class CheckBoxTableCellTest extends Application {
@Override
public void start(Stage primaryStage) {
final TableView<Person> tableView = new TableView<>();
tableView.setItems(FXCollections.observableArrayList(
new Person("Robert", "Plant"),
new Person("Neil", "Young"),
new Person("Willie", "Nelson"),
new Person("Natalie", "Merchant")
));
tableView.getItems().get(3).setVegetarian(true);
final TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
final TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
final TableColumn<Person, Boolean> vegetarianCol = new TableColumn<>("Vegetarian");
tableView.getColumns().addAll(firstNameCol, lastNameCol, vegetarianCol);
firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
vegetarianCol.setCellValueFactory(new PropertyValueFactory<>("vegetarian"));
vegetarianCol.setCellFactory(CheckBoxTableCell.forTableColumn(vegetarianCol));
vegetarianCol.setEditable(true);
tableView.setEditable(true);
final BorderPane root = new BorderPane();
root.setCenter(tableView);
final HBox controls = new HBox(5);
final Button infoButton = new Button("Show details");
infoButton.setOnAction(event -> {
for (Person p : tableView.getItems())
System.out.printf("%s %s (%svegetarian)%n", p.getFirstName(),
p.getLastName(), p.isVegetarian() ? "" : "not ");
System.out.println();
});
controls.getChildren().add(infoButton);
root.setBottom(controls);
Scene scene = new Scene(root, 300, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public static class Person {
private StringProperty firstName;
private StringProperty lastName;
private BooleanProperty vegetarian;
public Person(String firstName, String lastName) {
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
this.vegetarian = new SimpleBooleanProperty(false);
}
public String getFirstName() {
return firstName.get();
}
public String getLastName() {
return lastName.get();
}
public boolean isVegetarian() {
return vegetarian.get();
}
public void setFirstName(String firstName) {
this.firstName.set(firstName);
}
public void setLastName(String lastName) {
this.lastName.set(lastName);
}
public void setVegetarian(boolean vegetarian) {
this.vegetarian.set(vegetarian);
}
public StringProperty firstNameProperty() {
return firstName;
}
public StringProperty lastNameProperty() {
return lastName;
}
public BooleanProperty vegetarianProperty() {
return vegetarian;
}
}
}