Search code examples
javajavafxtableviewjavafx-8action

Deleting Row From Button Column Within a TableView [Java]


I have a TableView which generates buttons all along a column:

My program

Building a task-managing application. I want to be able to delete the row on which the button is located, not the row which is selected as shown here, when the corresponding button is pressed.

My table class implements EventHandler so the buttons in my TableView run the handle() method when pressed:

public TableList(String task, String subject, LocalDate dueDate) {
    this.task = new SimpleStringProperty(task);
    this.subject = new SimpleStringProperty(subject);
    this.dueDate = dueDate;
    this.completed = new JFXButton("Finished");
    completed.setOnAction(this);
}


@Override
public void handle(ActionEvent event) {
    // DELETE ROW HERE
}

The only thing missing is how to detect the row on which the buttons are pressed and then delete it (since all the buttons run the same handle method). Help much appreciated.

Code dump here for clarity: https://pastebin.com/TGk4CUWh


Solution

  • Here is a demo. Altered code from here. The key is to use updateItem in TableCell. In the Button's onAction, remove from the TableView at the current index of the Button. getIndex() gets the buttons current index.

    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    
    public class JustDoIt extends Application
    {
    
        private final TableView<Person> table = new TableView<>();
        private final ObservableList<Person> data
                = FXCollections.observableArrayList(
                        new Person("Jacob", "Smith"),
                        new Person("Isabella", "Johnson"),
                        new Person("Ethan", "Williams"),
                        new Person("Emma", "Jones"),
                        new Person("Michael", "Brown")
                );
    
        public static void main(String[] args)
        {
            launch(args);
        }
    
        @Override
        public void start(Stage stage)
        {
            stage.setWidth(450);
            stage.setHeight(500);
    
            TableColumn firstNameCol = new TableColumn("First Name");
            firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
    
            TableColumn lastNameCol = new TableColumn("Last Name");
            lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
    
            TableColumn actionCol = new TableColumn("Action");
            actionCol.setCellValueFactory(new PropertyValueFactory<>("DUMMY"));
    
            Callback<TableColumn<Person, String>, TableCell<Person, String>> cellFactory
                    = //
                    new Callback<TableColumn<Person, String>, TableCell<Person, String>>()
            {
                @Override
                public TableCell call(final TableColumn<Person, String> param)
                {
                    final TableCell<Person, String> cell = new TableCell<Person, String>()
                    {
    
                        final Button btn = new Button("Just Do It");
    
                        {
                            btn.setOnAction(event -> {
                                table.getItems().remove(getIndex());
                            });
                        }
    
                        @Override
                        public void updateItem(String item, boolean empty)
                        {
                            super.updateItem(item, empty);
                            if (empty) {
                                setGraphic(null);
                                setText(null);
                            }
                            else {
                                setGraphic(btn);
                                setText(null);
                            }
                        }
                    };
                    return cell;
                }
            };
    
            actionCol.setCellFactory(cellFactory);
    
            table.setItems(data);
            table.getColumns().addAll(firstNameCol, lastNameCol, actionCol);
    
            Scene scene = new Scene(new Group());
    
            ((Group) scene.getRoot()).getChildren().addAll(table);
    
            stage.setScene(scene);
            stage.show();
        }
    
        public static class Person
        {
    
            private final SimpleStringProperty firstName;
            private final SimpleStringProperty lastName;
    
            private Person(String fName, String lName)
            {
                this.firstName = new SimpleStringProperty(fName);
                this.lastName = new SimpleStringProperty(lName);
            }
    
            public String getFirstName()
            {
                return firstName.get();
            }
    
            public void setFirstName(String fName)
            {
                firstName.set(fName);
            }
    
            public String getLastName()
            {
                return lastName.get();
            }
    
            public void setLastName(String fName)
            {
                lastName.set(fName);
            }
    
        }
    }