JavaFX PropertyValueFactory无法从位于不同包中的类接收属性

时间:2019-03-15 01:28:52

标签: java javafx package

我有两个软件包,一个用于对象,另一个用于创建GUI。我正在尝试在JavaFX中创建TableView,并且必须使用PropertyValuesFactory<>(property)来获取对象的值。因此,我有一个错误:如果将Person和GUI类放在同一个程序包中,则一切正常,但是将Person类放入对象程序包时,一切都会变坏,并且出现此错误:

WARNING: Can not retrieve property 'name' in PropertyValueFactory: javafx.scene.control.cell.PropertyValueFactory@6771b7fb with provided class type: class uni.rest.objects.Person
    java.lang.RuntimeException: java.lang.IllegalAccessException: module javafx.base cannot access class uni.rest.objects.Person (in module main) because module main does not open uni.rest.objects to javafx.base

这也是发生错误的代码行:

person_column.setCellValueFactory(new PropertyValueFactory<>("name"));

因此,我假设可能必须更改属性值的位置... 我将不胜感激任何帮助。

2 个答案:

答案 0 :(得分:3)

PropertyValueFactory类使用反射来访问模型类的属性。 Java 9中添加的模块系统增加了更大的封装,这可以防止模块反射地访问其他模块,除非module-info.java中的指令给予了许可。

PropertyValueFactory的{​​{3}}提到了将应用程序作为模块部署时需要做的事情:

  

将应用程序部署为模块

     

如果所引用的类在命名模块中,则javafx.base模块必须可以反射地访问它。如果模块documentation至少包含javafx.base模块的包含包,则该类可以反射地访问。否则,opens方法将记录警告并返回null

     

例如,如果Person类位于com.foo模块的foo.app包中,则module-info.java可能看起来像这样:

module foo.app {
    opens com.foo to javafx.base;
}
     

或者,如果模块call(TableColumn.CellDataFeatures)无条件包含包,则可以反射地访问类


另一个选择是放弃PropertyValueFactory并使用自定义CallbackPropertyValueFactory更加方便了lambda并不是问题。在lambda之前,如果要使用自定义Callback,则每次必须创建一个冗长的匿名类。由于使用了lambda,因此可以做到:

person_column.setCellValueFactory(features -> features.getValue().nameProperty());

很明显,如果模型公开了JavaFX属性,则效果最佳。自定义Callback的优点包括避免反射和类型安全。

答案 1 :(得分:0)

我有一个类似的问题,这是吸气功能的大写字母。 我正尝试与此一起访问

productIdColumn.setCellValueFactory(new PropertyValueFactory<Product, Integer>("id"));

这有效:

public int getId(){
    return this.id;
}

但是如果我有GetId或getid,它将给我错误。

这与PropertyValueFactory如何使用getter函数查找值有关。您可以在https://visdup.blogspot.com/2019/04/javafx-propertyvaluefactory-is-not-able.html

中详细了解其原因。