JavaFX 应用程序无法在 lambda 表达式上编译
JavaFX Application fails to compile on lambda expression
我正在尝试构建一个 JavaFX 应用程序来显示 TreeTableView。仍在设置这整个事情。我让它在没有 Product class 的情况下只使用一列,但我正在努力使其与 Product class 和两列一起使用。以下代码无法编译:
col1.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Product, String> param) -> param.getValue().getValue().getNameProperty());
并吐出这个错误:
Error:(38, 121) java: incompatible types: bad return type in lambda expression
java.lang.String cannot be converted to javafx.beans.value.ObservableValue<java.lang.String>
这是完整的代码:
public class Controller implements Initializable {
@FXML
private TreeTableView<Product> tableView;
@FXML
private TreeTableColumn<Product, String> col1;
@FXML
private TreeTableColumn<Product, String> col2;
TreeItem<Product> product1 = new TreeItem<>(new Product("Bread", "300g"));
TreeItem<Product> product2 = new TreeItem<>(new Product("Eggs", "5"));
TreeItem<Product> product3 = new TreeItem<>(new Product("Brad Pitt", "One and Only one"));
TreeItem<Product> product4 = new TreeItem<>(new Product("Moisturizer", "20"));
TreeItem<Product> product5 = new TreeItem<>(new Product("Horse Lubricant", "4"));
TreeItem<Product> root = new TreeItem<>(new Product("Name", "Quantity"));
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
root.getChildren().setAll(product1, product2, product3, product4, product5);
col1.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Product, String> param) -> param.getValue().getValue().getNameProperty());
col2.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Product, String> param) -> param.getValue().getValue().getQuantityProperty());
tableView.setRoot(root);
tableView.setShowRoot(false);
}
public class Product{
SimpleStringProperty nameProperty;
SimpleStringProperty quantityProperty;
public Product(String name, String quantity){
this.nameProperty = new SimpleStringProperty(name);
this.quantityProperty = new SimpleStringProperty(quantity);
}
public String getNameProperty() {
return nameProperty.get();
}
public SimpleStringProperty namePropertyProperty() {
return nameProperty;
}
public void setNameProperty(String nameProperty) {
this.nameProperty.set(nameProperty);
}
public String getQuantityProperty() {
return quantityProperty.get();
}
public SimpleStringProperty quantityPropertyProperty() {
return quantityProperty;
}
public void setQuantityProperty(String quantityProperty) {
this.quantityProperty.set(quantityProperty);
}
}
}
首先,你的Product
class不符合常规。通常,字段名称匹配 属性 名称(例如 name
,而不是 nameProperty
)。然后你用 属性 的名字命名你的 getter、setter 和 属性 getter。例如:
import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;
public class Product {
private final StringProperty name = new SimpleStringProperty(this, "name");
public final void setName(String name) { this.name.set(name); }
public final String getName() { return name.get(); }
public final StringProperty nameProperty() { return name; }
private final StringProperty quantity = new SimpleStringProperty(this, "quantity");
public final void setQuantity(String quantity) { this.quantity.set(quantity); }
public final String getQuantity() { return quantity.get(); }
public final StringProperty quantityProperty() { return quantity; }
public Product() {} // typically Java(FX)Beans provide no-arg constructors as well
public Product(String name, String quantity) {
setName(name);
setQuantity(quantity);
}
}
注意:你的class是一个非静态嵌套(即内部)class。这意味着每个 Product
实例都需要一个封闭 class 的实例。如果您想将 Product
保留为嵌套的 class,请考虑将其设为静态。我上面的例子假设 Product
在它自己的源文件中。
有了 class,您可以像这样定义单元格值工厂:
TreeTableColumn<Product, String> nameCol = ...;
nameCol.setCellValueFactory(data -> data.getValue().getValue().nameProperty());
TreeTableColumn<Product, String> quantityCol = ...;
quantityCol.setCellValueFactory(data -> data.getValue().getValue().quantityProperty());
注意工厂 return Product
实例的适当 属性。这解决了你的编译错误,因为 StringProperty
是 ObservableValue<String>
的一个实例。这也意味着您的 table 可以直接访问支持模型的 属性,这有助于使 table 保持最新并实现内联编辑。
如果有帮助,这里使用匿名 class 设置 nameCol
的单元格值工厂,它明确显示所有使用的类型:
nameCol.setCellValueFactory(new Callback<>() { // may have to explicitly define type arguments, depending on version of Java
@Override
public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<Product, String> data) {
TreeItem<Product> treeItem = data.getValue();
Product product = treeItem.getValue();
return product.nameProperty();
}
});
我正在尝试构建一个 JavaFX 应用程序来显示 TreeTableView。仍在设置这整个事情。我让它在没有 Product class 的情况下只使用一列,但我正在努力使其与 Product class 和两列一起使用。以下代码无法编译:
col1.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Product, String> param) -> param.getValue().getValue().getNameProperty());
并吐出这个错误:
Error:(38, 121) java: incompatible types: bad return type in lambda expression
java.lang.String cannot be converted to javafx.beans.value.ObservableValue<java.lang.String>
这是完整的代码:
public class Controller implements Initializable {
@FXML
private TreeTableView<Product> tableView;
@FXML
private TreeTableColumn<Product, String> col1;
@FXML
private TreeTableColumn<Product, String> col2;
TreeItem<Product> product1 = new TreeItem<>(new Product("Bread", "300g"));
TreeItem<Product> product2 = new TreeItem<>(new Product("Eggs", "5"));
TreeItem<Product> product3 = new TreeItem<>(new Product("Brad Pitt", "One and Only one"));
TreeItem<Product> product4 = new TreeItem<>(new Product("Moisturizer", "20"));
TreeItem<Product> product5 = new TreeItem<>(new Product("Horse Lubricant", "4"));
TreeItem<Product> root = new TreeItem<>(new Product("Name", "Quantity"));
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
root.getChildren().setAll(product1, product2, product3, product4, product5);
col1.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Product, String> param) -> param.getValue().getValue().getNameProperty());
col2.setCellValueFactory(
(TreeTableColumn.CellDataFeatures<Product, String> param) -> param.getValue().getValue().getQuantityProperty());
tableView.setRoot(root);
tableView.setShowRoot(false);
}
public class Product{
SimpleStringProperty nameProperty;
SimpleStringProperty quantityProperty;
public Product(String name, String quantity){
this.nameProperty = new SimpleStringProperty(name);
this.quantityProperty = new SimpleStringProperty(quantity);
}
public String getNameProperty() {
return nameProperty.get();
}
public SimpleStringProperty namePropertyProperty() {
return nameProperty;
}
public void setNameProperty(String nameProperty) {
this.nameProperty.set(nameProperty);
}
public String getQuantityProperty() {
return quantityProperty.get();
}
public SimpleStringProperty quantityPropertyProperty() {
return quantityProperty;
}
public void setQuantityProperty(String quantityProperty) {
this.quantityProperty.set(quantityProperty);
}
}
}
首先,你的Product
class不符合常规。通常,字段名称匹配 属性 名称(例如 name
,而不是 nameProperty
)。然后你用 属性 的名字命名你的 getter、setter 和 属性 getter。例如:
import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;
public class Product {
private final StringProperty name = new SimpleStringProperty(this, "name");
public final void setName(String name) { this.name.set(name); }
public final String getName() { return name.get(); }
public final StringProperty nameProperty() { return name; }
private final StringProperty quantity = new SimpleStringProperty(this, "quantity");
public final void setQuantity(String quantity) { this.quantity.set(quantity); }
public final String getQuantity() { return quantity.get(); }
public final StringProperty quantityProperty() { return quantity; }
public Product() {} // typically Java(FX)Beans provide no-arg constructors as well
public Product(String name, String quantity) {
setName(name);
setQuantity(quantity);
}
}
注意:你的class是一个非静态嵌套(即内部)class。这意味着每个 Product
实例都需要一个封闭 class 的实例。如果您想将 Product
保留为嵌套的 class,请考虑将其设为静态。我上面的例子假设 Product
在它自己的源文件中。
有了 class,您可以像这样定义单元格值工厂:
TreeTableColumn<Product, String> nameCol = ...;
nameCol.setCellValueFactory(data -> data.getValue().getValue().nameProperty());
TreeTableColumn<Product, String> quantityCol = ...;
quantityCol.setCellValueFactory(data -> data.getValue().getValue().quantityProperty());
注意工厂 return Product
实例的适当 属性。这解决了你的编译错误,因为 StringProperty
是 ObservableValue<String>
的一个实例。这也意味着您的 table 可以直接访问支持模型的 属性,这有助于使 table 保持最新并实现内联编辑。
如果有帮助,这里使用匿名 class 设置 nameCol
的单元格值工厂,它明确显示所有使用的类型:
nameCol.setCellValueFactory(new Callback<>() { // may have to explicitly define type arguments, depending on version of Java
@Override
public ObservableValue<String> call(TreeTableColumn.CellDataFeatures<Product, String> data) {
TreeItem<Product> treeItem = data.getValue();
Product product = treeItem.getValue();
return product.nameProperty();
}
});