在JavaFX中呈现TableColumns的通用方法

时间:2018-07-27 07:16:38

标签: java javafx tableview

因此,我的应用程序在不同的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之类的替代方法,但是它们都返回了错误。控制器只能作为参数传递。还是这是一个很糟糕的做法/表现不佳的事情?

1 个答案:

答案 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);
    }
}