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
After pressing lots of "Remove" buttons: