Get Checkbox value in a table in JavaFX

java, javafx, javafx-2

Solution

Tested on Java 8. Only 4 simple things.

1) Make CheckBoxCellFactory class. Put somewhere in your project.

public class CheckBoxCellFactory implements Callback {
    @Override
    public TableCell call(Object param) {
        CheckBoxTableCell<Person,Boolean> checkBoxCell = new CheckBoxTableCell();
        return checkBoxCell;
    }
}

2) Your model class. Person for example.

public static class Person {
   private SimpleBooleanProperty checked = new SimpleBooleanProperty(false);
   // other columns here

    public SimpleBooleanProperty checkedProperty() {
        return this.checked;
    }

    public java.lang.Boolean getChecked() {
        return this.checkedProperty().get();
    }

    public void setChecked(final java.lang.Boolean checked) {
        this.checkedProperty().set(checked);
    }

    // getter/setter for other columns

}

3) Made modifications in your fxml file. The section of your TableView -> TableColumn gonna look like this:

<TableColumn fx:id="checkBoxTableColumn" maxWidth="34.0" minWidth="26.0" prefWidth="34.0" resizable="false" sortable="false">   
<cellValueFactory><PropertyValueFactory property="checked" /></cellValueFactory>
<cellFactory><partarch.fx.CheckBoxCellFactory /></cellFactory>
</TableColumn>

4) If you want to make your checkbox being editable

- 4.1 Open fxml in the Scene Builder.

- 4.2 Select checkBox column and then check "Editable" property in the Properties pane.

- 4.3 Select TableView containing your checkbox and do the same(check "Editable" property in the Properties pane).

Implementation in binaries on SF and source on GitHub

Problem

I have a table and it has a column with checkboxes. On a button click I want to find out which checkboxes are checked and which are not. So far I managed to create checkboxes in a table. The code is as follows. ``` public class TTEs implements Initializable { @FXML private TableView<TestObject> tableReport; @FXML private TableColumn<TestObject, String> name; @FXML private TableColumn<TestObject, Boolean> checkbox; @FXML public void getValues() { //the method will get what check boxes are checked (this part is the problem) } @Override public void initialize(URL arg0, ResourceBundle arg1) { ObservableList<TestObject> data = FXCollections.observableArrayList(); data.add(new TestObject("Test 1", true)); data.add(new TestObject("Test 2", false)); tableReport.setItems(data); name.setCellValueFactory(new PropertyValueFactory<TestObject, String>("name")); checkbox.setCellValueFactory(new PropertyValueFactory<TestObject, Boolean>("checked")); checkbox.setCellFactory(new Callback<TableColumn<TestObject, Boolean>, TableCell<TestObject, Boolean>>() { public TableCell<TestObject, Boolean> call(TableColumn<TestObject, Boolean> p) { return new CheckBoxTableCell<TestObject, Boolean>(); } }); } //CheckBoxTableCell for creating a CheckBox in a table cell public static class CheckBoxTableCell<S, T> extends TableCell<S, T> { private final CheckBox checkBox; private ObservableValue<T> ov; public CheckBoxTableCell() { this.checkBox = new CheckBox(); this.checkBox.setAlignment(Pos.CENTER); setAlignment(Pos.CENTER); setGraphic(checkBox); } @Override public void updateItem(T item, boolean empty) { super.updateItem(item, empty); if (empty) { setText(null); setGraphic(null); } else { setGraphic(checkBox); if (ov instanceof BooleanProperty) { checkBox.selectedProperty().unbindBidirectional((BooleanProperty) ov); } ov = getTableColumn().getCellObservableValue(getIndex()); if (ov instanceof BooleanProperty) { checkBox.selectedProperty().bindBidirectional((BooleanProperty) ov); } } } } } ``` When I debug, I find that: ``` ov = getTableColumn().getCellObservableValue(getIndex()); if (ov instanceof BooleanProperty) { checkBox.selectedProperty().bindBidirectional((BooleanProperty) ov); } ``` In the above condition, it never goes inside the `if` statement, meaning that the `ov` is not an instance of `BooleanProperty`. But when I print the class of `ov`, ``` System.out.println(ov.getClass().getName()); ``` it prints as ``` javafx.beans.property.ReadOnlyObjectWrapper ``` `ReadOnlyObjectWrapper` is a subclass of `BooleanProperty`, so why is the `instanceof` check not working?

Original source