问题描述
我有两个软件包,一个用于对象,另一个用于创建GUI.我正在尝试在JavaFX中创建TableView
,并且必须使用PropertyValuesFactory<>(property)
来获取对象的值.因此,我有一个错误:如果将Person和GUI类放在同一个程序包中,则一切正常,但是将Person类放入对象程序包时,一切都会变坏,并且出现此错误:
I have two packages, one for objects and the other for creating GUI. I am trying to create a TableView
in JavaFX and I have to use PropertyValuesFactory<>(property)
to get the value of the object. So I have a bug where if I put the Person and GUI class in the same package everything would work for fine, but when the Person class is put in the objects package everything goes bad and I get this error:
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
这也是发生错误的代码行:
This is also the line of code where the error happens:
person_column.setCellValueFactory(new PropertyValueFactory<>("name"));
因此,我认为可能必须更改属性值的位置...我将不胜感激任何帮助.
So I assume that the property value location might have to be changed...I would appreciate any help.
推荐答案
PropertyValueFactory
类使用反射来访问模型类的属性. Java 9中添加的模块系统增加了更大的封装,这可以防止模块反射地访问其他模块,除非得到module-info.java
中的指令允许.
The PropertyValueFactory
class uses reflection to access the model class' properties. The module system added in Java 9 adds greater encapsulation which prevents modules from reflectively accessing other modules unless given permission by directives in module-info.java
.
的文档 PropertyValueFactory
提到了将应用程序作为模块部署时需要做的事情:
The documentation of PropertyValueFactory
mentions what you need to do if deploying your application as a module:
如果引用的类在命名模块中,则javafx.base
模块必须可以反射地访问它.如果模块至少将javafx.base
模块的包含包打开.否则, call(TableColumn.CellDataFeatures)
方法将记录警告并返回null
.
If the referenced class is in a named module, then it must be reflectively accessible to the javafx.base
module. A class is reflectively accessible if the module opens the containing package to at least the javafx.base
module. Otherwise the call(TableColumn.CellDataFeatures)
method will log a warning and return null
.
例如,如果Person
类位于foo.app
模块的com.foo
包中,则module-info.java
可能看起来像这样:
For example, if the Person
class is in the com.foo
package in the foo.app
module, the module-info.java
might look like this:
module foo.app {
opens com.foo to javafx.base;
}
或者,如果模块无条件导出包含的包
Alternatively, a class is reflectively accessible if the module exports the containing package unconditionally
另一个选择是放弃PropertyValueFactory
并使用自定义的Callback
.当lambda不是问题时,PropertyValueFactory
更为方便.在lambda之前,如果要使用自定义Callback
,则每次必须创建一个冗长的匿名类.由于使用lambda,因此可以做到:
Another option is to forgo PropertyValueFactory
and use a custom Callback
. The PropertyValueFactory
was more of a convenience for when lambdas were not a thing; before lambdas, if one wanted to use a custom Callback
, one would have to create an anonymous class each time which was verbose. Since lambdas, however, one can do:
person_column.setCellValueFactory(features -> features.getValue().nameProperty());
很显然,如果模型公开了JavaFX属性,则效果最佳.自定义Callback
的优点包括避免反射和类型安全.
Obviously, this works best if the model exposes a JavaFX property. The advantages of a custom Callback
include avoidance of reflection and type safety.
这篇关于JavaFX PropertyValueFactory无法从位于不同包中的类接收属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!