Home > Enterprise >  How to listen for clicks on dynamically generated buttons in TableCell?
How to listen for clicks on dynamically generated buttons in TableCell?

Time:05-18

I have a class Task that takes field values from the database and is displayed as a row in the table.

package com.example.javafxapp.models;

import javafx.scene.control.Button;
import javafx.scene.layout.HBox;

public class Task {
    private String id;
    private String task;
    private Button done;
    private Button cancel;
    private Button remove;
    private HBox edit;


    public Task(String id, String task, HBox edit, Button done, Button cancel, Button remove) {
        this.id = id;
        this.task = task;
        this.edit = edit;
        this.done = done;
        this.cancel = cancel;
        this.remove = remove;

        edit.getChildren().addAll(done, cancel, remove);
        edit.setSpacing(5);
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTask() {
        return task;
    }

    public void setTask(String task) {
        this.task = task;
    }
    public HBox getEdit() {
        return edit;
    }

    public void setEdit(HBox edit) {
        this.edit = edit;
    }

    public Button getDone() {
        return done;
    }

    public void setDone(Button done) {
        this.done = done;
    }

    public Button getCancel() {
        return cancel;
    }

    public void setCancel(Button cancel) {
        this.cancel = cancel;
    }

    public Button getRemove() {
        return remove;
    }

    public void setRemove(Button remove) {
        this.remove = remove;
    }
}

There is a controller that fills the rows of the table with objects of the Task class.

package com.example.javafxapp.controllers;

import com.example.javafxapp.models.DatabaseHandler;
import com.example.javafxapp.models.Task;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

import java.io.IOException;
import java.net.URL;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Optional;
import java.util.ResourceBundle;

public class AppController {

    @FXML
    private ResourceBundle resources;

    @FXML
    private URL location;

    @FXML
    private AnchorPane appPane;

    @FXML
    private TableView<Task> currentTable;

    @FXML
    private Tab currentTab;

    @FXML
    private AnchorPane currentTabAnchorPane;

    @FXML
    private TableColumn<Task, String> currentIdColumn;

    @FXML
    private TableColumn<Task, String> currentTasksColumn;

    @FXML
    private TableColumn<Task, HBox> editColumn;


    ObservableList<Task> currentTasks = FXCollections.observableArrayList();

    @FXML
    void initialize() {

        getAllTasks();
        initCols();

        //Вutton mouse click listener from Tableview cells.

    }

    private void initCols(){
        currentIdColumn.setCellValueFactory(new PropertyValueFactory<Task, String>("id"));
        currentTasksColumn.setCellValueFactory(new PropertyValueFactory<Task, String>("task"));
        editColumn.setCellValueFactory(new PropertyValueFactory<Task, HBox>("edit"));

        currentTable.getItems().clear();
        currentTable.setItems(currentTasks);
    }

    private void getAllTasks() {
        ResultSet rs = new DatabaseHandler().getTaskTableFromDb();
            try {
                while (rs.next()) {
                    if(rs.getString("state").equals("current")) {
                        currentTasks.add(new Task(rs.getString("idtask"),
                                rs.getString("task"),
                                rs.getString("state"),
                                new HBox(),
                                new Button("done"),
                                new Button("cancel"),
                                new Button("remove")));
                    }
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
    }
}

I need to listen for clicks on buttons in cells. But those buttons are not present as fields in the controller. How can I do this without referring to a specific cell?

CodePudding user response:

Your model class Task should not have any Ui components in it. It should look something like

public class Task {
    private String id;
    private String task;


    public Task(String id, String task) {
        this.id = id;
        this.task = task;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTask() {
        return task;
    }

    public void setTask(String task) {
        this.task = task;
    }
}

You should strongly consider implementing the model class with enter image description here

After pressing lots of "Remove" buttons:

enter image description here

  • Related