9

I currently have a problem with setting a CheckBoxTableCell from the FXML. I tried to convert this code to FXML:

tableCol.setCellValueFactory(new PropertyValueFactory<Product, Boolean>("property"));
tableCol.setCellFactory(CheckBoxTableCell.forTableColumn(toStockCol));

where 'property' is just some attribute of the 'Product' Class (from type 'boolean'). This code works fine. I now try to set this in the FXML, like this:

<TableColumn text="Some Col">
    <cellValueFactory><PropertyValueFactory property="property" /></cellValueFactory>
    <cellFactory><CheckBoxTableCell editable="true" /></cellFactory>
</TableColumn>

This doesn't work, I get the following error (which is a FXML LoadExeption):

Caused by: java.lang.IllegalArgumentException: Unable to coerce CheckBoxTableCell@24d62d1e[styleClass=cell indexed-cell table-cell check-box-table-cell]'null' to interface javafx.util.Callback.
at com.sun.javafx.fxml.BeanAdapter.coerce(BeanAdapter.java:495)
at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:258)
at com.sun.javafx.fxml.BeanAdapter.put(BeanAdapter.java:54)
at javafx.fxml.FXMLLoader$PropertyElement.set(FXMLLoader.java:1409)
at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:786)
at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2827)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2536)
... 42 more

I can not figure out what I am doing wrong. Also, in my opinion there is little to none documentation about how to set a CheckBox in a TableView with FXML.

Note: I would like to set this from the FXML, because it seems to be the spot for this. I know this can be done with the FXML controller. Also, I am just curious.

Any help is greatly appreciated!

bashoogzaad
  • 4,611
  • 8
  • 40
  • 65

2 Answers2

8

Unfortunately CheckBoxTableCell is not a factory, and there is none available in the JavaFX package. You have to write your own factory.

public class CheckBoxTableCellFactory<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> {
    public TableCell<S, T> call(TableColumn<S, T> param) {
        return new CheckBoxTableCell<S,T>();
    }
}

Then you can define your table column in the FXML file as:

<TableColumn text="Some Col">
    <cellValueFactory><PropertyValueFactory property="property" />     </cellValueFactory>
    <cellFactory><CheckBoxTableCellFactory /></cellFactory>
</TableColumn>

Don“t forget to include the CheckBoxTableCellFactory or else to declare the full path like org.my.CheckBoxTableCellFactory or the loader will give you a not found exception.

codewing
  • 674
  • 8
  • 25
Antonio Raposo
  • 523
  • 6
  • 9
1

If you like to manage all in FXML here is how to do it.

Don't forget to add <?language javascript?> to FXML header, but keep in mind that JavaScript engine Nashorn is deprecated since Java 11.

<TableColumn text="Married" fx:id="married">
   <cellValueFactory>
      <PropertyValueFactory property="married" />
   </cellValueFactory>
</TableColumn>
<fx:script>
   var myCellValue =
      javafx.scene.control.cell.CheckBoxTableCell.forTableColumn( married );
   married.setCellFactory(myCellValue);
</fx:script>

Your data model should be exposed as below.

private final SimpleBooleanProperty married = new SimpleBooleanProperty( false );

public SimpleBooleanProperty marriedProperty(){
   return married;
}
Aubin
  • 14,617
  • 9
  • 61
  • 84