JavaFX: Include Button into cell for TableView

There are times when you need to have an Button for each of the row in the TableView, hence in this post I will go through how we could add a Button into the row of the TableView.

c3 will be the column that I am adding the Button to. Instead of the typical TextFieldTableCell, we would be creating a CallBack for both the setCellValueFactory and setCellFactory. Whereby in the setCellFactory, we would be creating a ButtonCell which is a custom class that extend the TableCell.

Another important point to note is that you can use getTableRow().getIndex() to get the selected row and therefore obtain the object that you want to remove.

@FXML private TableView tableNewBoM;
private void prepareBoMTable() {
    tableNewBoM.getItems().clear();
    tableNewBoM.getColumns().clear();
    TableColumn c1 = new TableColumn("Item");
    c1.setCellValueFactory(new PropertyValueFactory<BillOfMaterial, String>("itemID"));
    c1.setCellFactory(TextFieldTableCell.forTableColumn());
    c1.setMinWidth(200);

    TableColumn c2 = new TableColumn("Qty");
    c2.setCellValueFactory(new PropertyValueFactory<BillOfMaterial, String>("quantity"));
    c2.setCellFactory(TextFieldTableCell.forTableColumn());

    TableColumn c3 = new TableColumn<>("Action");
    c3.setSortable(false);
    c3.setCellValueFactory(
            new Callback<TableColumn.CellDataFeatures<BillOfMaterial, Boolean>,
                    ObservableValue<Boolean>>() {

                @Override
                public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<BillOfMaterial, Boolean> p) {
                    return new SimpleBooleanProperty(p.getValue() != null);
                }
            });

    c3.setCellFactory(
            new Callback<TableColumn<BillOfMaterial, Boolean>, TableCell<BillOfMaterial, Boolean>>() {

                @Override
                public TableCell<BillOfMaterial, Boolean> call(TableColumn<BillOfMaterial, Boolean> p) {
                    return new ButtonCell(tableNewBoM);
                }
            });

    ObservableList<BillOfMaterial> data = FXCollections.observableArrayList(tempBoM);
    tableNewBoM.setItems(data);
    tableNewBoM.getColumns().addAll(c1, c2, c3);
}

The below is the code for creating the custom cell for the button.

private class ButtonCell extends TableCell<BillOfMaterial, Boolean> {
    final Button cellButton = new Button("Remove");

    ButtonCell(final TableView tblView){

        cellButton.setOnAction(new EventHandler<ActionEvent>(){

            @Override
            public void handle(ActionEvent t) {
                int selectedIndex = getTableRow().getIndex();
                BillOfMaterial toRemove = (BillOfMaterial) tblView.getItems().get(selectedIndex);
                tempBoM.remove(toRemove);
                prepareBoMTable();
            }
        });
    }

    //Display button if the row is not empty
    @Override
    protected void updateItem(Boolean t, boolean empty) {
        super.updateItem(t, empty);
        if(!empty){
            setGraphic(cellButton);
        }
    }
}

The end result would be as shown below.

sample_tableview

 

Lastly, I would like to thanks JAVA-BUDDY for the great tutorial that I had referred to while coding the above.

Advertisements
This entry was posted in Java, JavaFX and tagged , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s