The problem in Java FX when we hide controls is that once we set it to setVisible(false), the control will be hidden yes. But its bounded space will still be in effect and it would look pretty ugly seeing a huge empty area in your user interface.
While some have suggested placing it in an HBox or VBox and removing and adding them when needed, the better solution for me is to call this control.managedProperty().bind(control.visibleProperty()); before any calls to setVisible() whether you want to hide it or not.
Once that is called, when you hide a control, its bounded space will be removed from the user interface as well making it look like it is not there at all.
The answer to this problem is that the object that you pass into the TableCell must have a boolean property inside of it that you need to bind to the table column.
If not, then the item and empty parameters in the updateItem() method of the TableCell class will always return null and true so there is no way to be able to determine when the CheckBox control should appear for rows that are present.
If you call setGraphic(checkbox) without adding any conditions, then every row visible in the TableView will have its own checkbox regardless if it has only a few rows.
Just add a BooleanProperty in your custom object and bind it to the TableCell value factory and you should see those checkbox.