(在这个问题之后,这就是提示它的原因(
我有一个带有LongProperty
的模型类:
public class Model {
private final SimpleLongProperty number = new SimpleLongProperty(this, "number");
public long getNumber() { return number.get(); }
public void setNumber(long number) { this.number.set(number); }
public LongProperty numberProperty() { return number; }
}
现在,在我的控制器中,我有一个要绑定到此属性的TableColumn<Model, Long> colNumber
。我知道我可以使用PropertyValueFactory
,但是当我可以通过编程方式传递属性并让编译器/IDE对我进行拼写检查时,我不喜欢按名称赋予属性的想法。基本上我想做这样的事情(我实际上想让它更简洁,最后的例子(:
colNumber.setCellValueFactory( cdf -> cdf.getValue().numberProperty() );
但这给了我一个编译错误:
Java:不兼容的类型:lambda 表达式中的错误返回类型 javafx.beans.property.ObjectProperty 无法转换为 javafx.beans.value.ObservableValue
正如我所说,我知道我可以使用PropertyValueFactory
,并且属性名称也有静态的最终字符串,但我发现它不那么优雅。有没有办法使这种程序化方法起作用?一些施法魔法?
附录:
我想制作它的实际方法是使用辅助方法:
private <S,T> Callback<CellDataFeatures<S,T>, ObservableValue<T>> propertyFactory(Callback<S, ObservableValue<T>> callback) {
return cdf-> callback.call(cdf.getValue());
}
然后我就可以使用
colNumber.setCellValueFactory(propertyFactory(Model::numberProperty));
这使我的代码非常简洁易读,并让编译器检查我的拼写错误等。
你可以做
colNumber.setCellValueFactory( cdf -> cdf.getValue().numberProperty().asObject() );
我认为(我需要测试,但这似乎是正确的(您还可以利用模型中的自动装箱和取消装箱,并将该属性实现为ObjectProperty<Long>
:
public class Model {
private final ObjectProperty<Long> number = new SimpleObjectProperty<>(this, "number", 0L);
public long getNumber() { return number.get(); }
public void setNumber(long number) { this.number.set(number); }
public ObjectProperty<Long> numberProperty() { return number; }
}
这种方法的一个缺点是它不允许任何算术绑定,例如你不能做someValue.bind(model.numberProperty().multiply(2));
等(另一个是你可能会意外调用model.numberProperty().set(null);
,并造成各种破坏。
当然,另一种解决方案是使您的表列成为TableColumn<Model, Number>
,但可能还有其他原因不这样做。
FWIW,我肯定会主张避免PropertyValueFactory
.这是JavaFX 2.0中引入的一个方便类(即在我们有了lambda之前(,当时实现允许编译器检查的回调非常冗长。现在它基本上是多余的(恕我直言,应该弃用,或者至少应该实现您概述的那种实用方法(。