因此,我的应用程序在不同的FXMLViewControllers中使用了许多TableView,以呈现许多不同的JPA实体。下面的示例适用于JobSupplierParts。
/**
* renderDoubleColumn takes a TableColumn setting its value and type before setting up edit event handling.
* @param column the tableColumn to be set up.
* @param field the name of the field to be mapped to.
* @param methodName the set method name of the field.
*/
protected void renderDoubleColumn(TableColumn<JobSupplierPart, Double> column, String field, String methodName) {
String className = "BiasDB.JobSupplierPart";
column.setCellValueFactory(new PropertyValueFactory<>(field));
column.setCellFactory(TextFieldTableCell.<JobSupplierPart, Double>forTableColumn(new DoubleStringConverter()));
column.setOnEditCommit(
new EventHandler<TableColumn.CellEditEvent<JobSupplierPart, Double>>() {
@Override
public void handle(TableColumn.CellEditEvent<JobSupplierPart, Double> t) {
JobSupplierPart supplierPart = t.getTableView().getItems().get(t.getTablePosition().getRow());
try {
Class<?> c = Class.forName(className);
Method method = c.getDeclaredMethod(methodName, Double.class);
method.invoke(supplierPart, t.getNewValue());
supplierPart.setTotal(updateItem(supplierPart));
} catch (ClassNotFoundException|NoSuchMethodException|IllegalAccessException|InvocationTargetException ex) {
logger.error("renderDoubleColumn",ex);
} //End try to get method from String.
try {
jobSupplierPartController.edit(supplierPart);
} catch (Exception ex) {
logger.error("renderDoubleColumn",ex);
}
t.getTableView().refresh();
}
} //END Event Handler
); //END SetOnEditCommit.
}
//END renderDoubleColumn
我可以这样称呼:
renderDoubleColumn(discountColumn, "discount", "setDiscount");
但是-我必须为每个JPA实体创建新方法。是否可以替换对JobSupplierPart的引用,使其像我用这些方法实现的那样成为通用方法?我已经尝试过T和K之类的替代方法,但是它们都返回了错误。控制器只能作为参数传递。还是这是一个很糟糕的做法/表现不佳的事情?
答案 0 :(得分:0)
因此,我不知道Java爱好者是否会同意这种解决方案,但是为了回应发布的答案,然后在我能够使代码更整洁后不久将其删除。我也将“设置/编辑”部分移到一个方法中,所以现在有了:
/**
* renderBigDecimalColumn takes a TableColumn setting its value and type before setting up edit event handling.
* @param column the tableColumn to be set up.
* @param field the name of the field to be mapped to.
*/
private void renderBigDecimalColumn(TableColumn<AccountAsset, BigDecimal> column, String field) {
//Set an observable value for the column
column.setCellValueFactory(new PropertyValueFactory<>(field));
//Set how we want the cell to be rendered
// This line varies for the different cell types e.g. Strings, Bools etc.
column.setCellFactory(TextFieldTableCell.<AccountAsset, BigDecimal>forTableColumn(new BigDecimalStringConverter()));
//Set how we want the cell to be edited including the row update.
column.setOnEditCommit(t -> {
handleEditCommit(t, field);
}); //END SetOnEditCommit.
} //END renderBigDecimalColumn
我的handleEditCommit方法如下:
/** handleEditCommit deals with updating and saving the new data from the table view.
*
* @param t
* @param field
*/
private void handleEditCommit(javafx.scene.control.TableColumn.CellEditEvent<AccountAsset,?> t, String field) {
AccountAsset rowData = t.getTableView().getItems().get(t.getTablePosition().getRow());
//Set the new value.
try {
BeanUtils.setProperty(rowData, field, t.getNewValue());
} catch (IllegalAccessException | InvocationTargetException ex) {
logger.error("handleEditCommit / Setter", ex);
}
//Save the new rowData back to the database.
try {
tableDataController.edit(rowData);
} catch (Exception ex) {
logger.error("handleEditCommit / Edit", ex);
}
}