JavaFX 8 如何传递和使用对没有 return 值的方法的引用?
JavaFX 8 How to pass and use a reference to a method that doesn't return a value?
我正在尝试传递和使用对另一个方法的方法引用。该引用是对 TableView 模型 class 中的 setter 的引用,该模型接受字符串输入参数并且不 return 值。
在我的 FMXL 控制器中,我正在动态创建 table 包含组合框的列。该代码基于 James_D 的解决方案:。我传递的方法参考如下:
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 控制器中遇到错误 ("method createComboBoxColumn in class DAOGenUtil cannot be applied to given types")。 BiConsumer<S, String> methodSetComboField
没有产生错误,但我不知道如何在 setOnAction 中使用它。
有人可以帮忙吗?我正在使用 JavaFX8、NetBeans 8.2 和 Scene Builder 8.3。
DBComboChoice 是一个 class,它包含一个 masterCode 和一个 masterDescription,例如。 "F" 代表 "Female","M" 代表 "Male"。 masterCode 存储在 TableView 的模型中。 masterDescription 显示在 ComboBox 中。我正在从主数据库 table.
加载值
这里是 TableView 数据模型的相关位class:
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
,因此您需要一个函数式接口,其中包含一个接受 2 个参数的方法:TestModel
和 String
。您可以轻松自己创建这样的界面
@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);
...
}
我正在尝试传递和使用对另一个方法的方法引用。该引用是对 TableView 模型 class 中的 setter 的引用,该模型接受字符串输入参数并且不 return 值。
在我的 FMXL 控制器中,我正在动态创建 table 包含组合框的列。该代码基于 James_D 的解决方案:
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 控制器中遇到错误 ("method createComboBoxColumn in class DAOGenUtil cannot be applied to given types")。 BiConsumer<S, String> methodSetComboField
没有产生错误,但我不知道如何在 setOnAction 中使用它。
有人可以帮忙吗?我正在使用 JavaFX8、NetBeans 8.2 和 Scene Builder 8.3。
DBComboChoice 是一个 class,它包含一个 masterCode 和一个 masterDescription,例如。 "F" 代表 "Female","M" 代表 "Male"。 masterCode 存储在 TableView 的模型中。 masterDescription 显示在 ComboBox 中。我正在从主数据库 table.
加载值这里是 TableView 数据模型的相关位class:
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
,因此您需要一个函数式接口,其中包含一个接受 2 个参数的方法:TestModel
和 String
。您可以轻松自己创建这样的界面
@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);
...
}