我有一个 TableView,我在其中显示数据库中的数据。TableView 本身并没有硬编码在特定的表上,而是添加了列和数据。我添加了上下文菜单,所以当用户右键单击一个项目时,它会删除它。它工作正常,但我不知道如何获取第一列的 ID。请注意,我不想要选定的索引,而是 tableView (第一列)中的 ID。
被质疑的片段:
removeMenuItem.setOnAction(event -> {
System.out.println(row.getItem()); // HERE
this.tableView.getItems().remove(row.getItem());
});
基本上,row.getItem()返回记录:
[2, Name, Stuff, Test Test, Category]
问题是如何获得 ID(在本例中为 2)或名称?
完整代码:
package controllers;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.util.Callback;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TableController {
@FXML
private Label descriptionLabel;
@FXML
private TableView tableView;
public void setTableResultSet(String label, ResultSet resultSet) throws SQLException {
// Create context menu
createContextMenu();
// Set label text
descriptionLabel.setText(label);
// Resolve columns
ObservableList<ObservableList> data = resolveTableColumns(resultSet);
// Add records
addTableRecords(resultSet, data);
}
/**
* Create a context menu responsible for removing items.
*/
private void createContextMenu() {
tableView.setRowFactory(tableView -> {
final TableRow row = new TableRow();
final ContextMenu contextMenu = new ContextMenu();
final MenuItem removeMenuItem = new MenuItem("Remove");
removeMenuItem.setOnAction(event -> {
System.out.println(row.getItem()); // HERE
this.tableView.getItems().remove(row.getItem());
});
contextMenu.getItems().add(removeMenuItem);
// Set context menu on row, but use a binding to make it only show for non-empty rows:
row.contextMenuProperty().bind(
Bindings.when(row.emptyProperty())
.then((ContextMenu) null)
.otherwise(contextMenu)
);
return row;
});
}
/**
* Resolves table columns based on a ResultSet.
*
* @param resultSet the ResultSet.
* @return
* @throws SQLException
*/
private ObservableList<ObservableList> resolveTableColumns(ResultSet resultSet) throws SQLException {
ObservableList<ObservableList> data = FXCollections.observableArrayList();
for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) {
final int j = i;
TableColumn col = new TableColumn(resultSet.getMetaData().getColumnName(i + 1));
col.setCellValueFactory((Callback<TableColumn.CellDataFeatures<ObservableList, String>, ObservableValue<String>>) param -> {
return new SimpleStringProperty(param.getValue().get(j).toString());
});
tableView.getColumns().add(col);
}
return data;
}
/**
* Adds table data from a ResultSet.
*
* @param resultSet the ResultSet.
* @param data the data.
* @throws SQLException
*/
private void addTableRecords(ResultSet resultSet, ObservableList<ObservableList> data) throws SQLException {
while (resultSet.next()) {
ObservableList<String> row = FXCollections.observableArrayList();
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
row.add(resultSet.getString(i));
}
data.add(row);
}
tableView.setItems(data);
}
}
根据@James_D 的评论进行编辑:
package controllers;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.util.Callback;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TableController {
@FXML
private Label descriptionLabel;
@FXML
private TableView<ObservableList<String>> tableView;
public void setTableResultSet(String label, ResultSet resultSet) throws SQLException {
// Create context menu
createContextMenu();
// Set label text
descriptionLabel.setText(label);
// Resolve columns
ObservableList<ObservableList<String>> data = resolveTableColumns(resultSet);
// Add records
addTableRecords(resultSet, data);
}
/**
* Create a context menu responsible for removing items.
*/
private void createContextMenu() {
tableView.setRowFactory(tableView -> {
final TableRow<ObservableList<String>> row = new TableRow<>();
final ContextMenu contextMenu = new ContextMenu();
final MenuItem removeMenuItem = new MenuItem("Изтрий");
removeMenuItem.setOnAction(event -> {
System.out.println(row.getItem().get(1));
this.tableView.getItems().remove(row.getItem());
});
contextMenu.getItems().add(removeMenuItem);
// Set context menu on row, but use a binding to make it only show for non-empty rows:
row.contextMenuProperty().bind(
Bindings.when(row.emptyProperty())
.then((ContextMenu) null)
.otherwise(contextMenu)
);
return row;
});
}
/**
* Resolves table columns based on a ResultSet.
*
* @param resultSet the ResultSet.
* @return
* @throws SQLException
*/
private ObservableList<ObservableList<String>> resolveTableColumns(ResultSet resultSet) throws SQLException {
ObservableList<ObservableList<String>> data = FXCollections.observableArrayList();
for (int i = 0; i < resultSet.getMetaData().getColumnCount(); i++) {
final int j = i;
TableColumn col = new TableColumn(resultSet.getMetaData().getColumnName(i + 1));
col.setCellValueFactory((Callback<TableColumn.CellDataFeatures<ObservableList, String>, ObservableValue<String>>) param -> {
return new SimpleStringProperty(param.getValue().get(j).toString());
});
tableView.getColumns().add(col);
}
return data;
}
/**
* Adds table data from a ResultSet.
*
* @param resultSet the ResultSet.
* @param data the data.
* @throws SQLException
*/
private void addTableRecords(ResultSet resultSet, ObservableList<ObservableList<String>> data) throws SQLException {
while (resultSet.next()) {
ObservableList<String> row = FXCollections.observableArrayList();
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
row.add(resultSet.getString(i));
}
data.add(row);
}
tableView.setItems(data);
}
}