JavaFX 8 如何传递和使用对不返回值的方法的引用?



我正在尝试传递并使用对另一个方法的方法引用。引用指向TableView的模型类中的一个setter,该类接受String输入参数并且不返回值。

在我的FMXL控制器中,我正在动态创建包含组合框的表列。该代码基于James_D的解决方案:Java FX ComboBoxTableCell Show In Every Cell。我通过方法参考如下:

TableColumn<TestModel, DBComboChoice> colComboBoxField = DAOGenUtil.createComboBoxColumn
("ComboBox Field",
TestModel::comboBoxFieldProperty, //this one works
TestModel::setComboBoxField, //this one doesn't work
comboData);

在createComboBoxColumn方法中,我被困在两个地方——方法声明和setOnAction中。

public <S> TableColumn<S, DBComboChoice> createComboBoxColumn(String title, 
Function<S, StringProperty> methodGetComboFieldProperty, 
//==>   <WHAT-GOES-HERE?> methodSetComboField,
ObservableList<DBComboChoice> comboData ) {
TableColumn<S, DBComboChoice> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> {
String masterCode =  methodGetComboFieldProperty.apply(cellData.getValue()).get();
DBComboChoice choice = DBComboChoice.getDescriptionByMasterCode(masterCode, comboData);
return new SimpleObjectProperty<>(choice);
});
col.setCellFactory((TableColumn<S, DBComboChoice> tablecol) -> {
ComboBox<DBComboChoice> combo = new ComboBox<>();
combo.getItems().addAll(comboData);
TableCell<S, DBComboChoice> cell = new TableCell<S, DBComboChoice>() {
@Override
protected void updateItem(DBComboChoice choice, boolean empty) {
super.updateItem(choice, empty);
if (empty) {
setGraphic(null);
} else {
combo.setValue(choice);
setGraphic(combo);
}
}
};
combo.setOnAction((ActionEvent event) -> {
String masterCode =  combo.getSelectionModel().getSelectedItem().getMasterCode();
//==>       col.getTableView().getItems().get(cell.getIndex()).<AND-HOW-DO-I-USE-IT-TO-SET-THE-DATA-MODEL'S-FIELD-TO-masterCode?>
});
return cell ;
});      
return col;
}

当我尝试Function<S, Void> methodSetComboField时,我在FXML控制器中遇到了一个错误("类DAOGenUtil中的方法createComboBoxColumn不能应用于给定的类型"(。BiConsumer<S, String> methodSetComboField没有生成错误,但我不知道如何在setOnAction中使用它。

有人能帮忙吗?我使用的是JavaFX8、NetBeans 8.2和Scene Builder 8.3。

DBComboChoice是一个包含masterCode和masterDescription的类,例如"F"表示"女性","M"表示"男性"。masterCode存储在TableView的模型中。主描述显示在组合框中。我正在从数据库主表加载值。

以下是TableView的数据模型类中的相关位:

public class TestModel {
//...
public String getComboBoxField() {
return comboBoxField.get();
}
public void setComboBoxField(String comboBoxField) {
this.comboBoxField.set(comboBoxField);
}
public StringProperty comboBoxFieldProperty() {
return comboBoxField;
}

//...
}

让我们看看可用的签名:

void setComboBoxField(String)

由于您不想指定实例而是使用TestModel::setComboBoxField,因此需要一个函数接口,该接口具有一个接受两个参数的方法:TestModelString。你可以自己创建这样一个界面很容易

@FunctionalInterface
public interface MyInterface<S, T> {
void call(S s, T t);
}
public <S> TableColumn<S, DBComboChoice> createComboBoxColumn(String title, 
Function<S, StringProperty> methodGetComboFieldProperty, 
MyInterface<? super S, ? super String> methodSetComboField,
ObservableList<DBComboChoice> comboData )

或者使用现有接口BiConsumer:

public <S> TableColumn<S, DBComboChoice> createComboBoxColumn(String title, 
Function<S, StringProperty> methodGetComboFieldProperty, 
BiConsumer<? super S, ? super String> methodSetComboField,
ObservableList<DBComboChoice> comboData ) {
...
methodSetComboField.accept(col.getTableView().getItems().get(cell.getIndex()), masterCode);
...
}

最新更新