"Element does not define a default property" 使用@DefaultProperty 时
"Element does not define a default property" when @DefaultProperty is used
我正在尝试创建一个用于 FXML 的自定义 JavaFX 元素,但是当 FXMLLoader
尝试解析它时,它会抛出一个异常,指出:
javafx.fxml.LoadException: Element does not define a default property.
但是,经过一些研究,我相信我正确定义了默认值 属性。
如果我包含 nestedCellValueFactory
标签,一切都会按预期进行。
Java
@DefaultProperty("nestedCellValueFactory")
public class NestablePropertyValueFactory<S, T> extends PropertyValueFactory<S, T> {
private ObjectProperty<PropertyValueFactory<?, ?>> nestedCellValueFactory;
public NestablePropertyValueFactory(
@NamedArg("property") String property,
@NamedArg("nestedCellValueFactory") PropertyValueFactory<?, ?> nestedCellValueFactory) {
super(property);
this.nestedCellValueFactory = new SimpleObjectProperty<>(this, "nestedCellValueFactory", nestedCellValueFactory);
}
public final ObjectProperty<PropertyValueFactory<?, ?>> nestedCellValueFactoryProperty() {
return nestedCellValueFactory;
}
public final PropertyValueFactory<?, ?> getNestedCellValueFactory() {
return nestedCellValueFactoryProperty().get();
}
public final void setNestedCellValueFactory(PropertyValueFactory<?, ?> nestedCellValueFactory) {
nestedCellValueFactoryProperty().set(nestedCellValueFactory);
}
}
FXML
<NestablePropertyValueFactory property="outer">
<NestablePropertyValueFactory property="inner">
<PropertyValueFactory property="property"/>
</NestablePropertyValueFactory>
</NestablePropertyValueFactory>
经过一些调试,我找到了错误的可能解释,但遗憾的是没有解决方案。
如果您 运行 没有 <nestedCellValueFactory>
标签,正如您已经报告的那样,您将得到这个例外:
Caused by: javafx.fxml.LoadException: Element does not define a default property.
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2597)
at javafx.fxml.FXMLLoader.access0(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$Element.set(FXMLLoader.java:180)
at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:790)
at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2823)
因此,转到 FXMLLoader
源来跟踪异常,您会发现:
第 790 行:parent.set(value);
,其中 parent
是 FXMLLoader$InstanceDeclarationElement
的实例,类型为 <your.package.name>. NestablePropertyValueFactory
,value
是一个 PropertyValueFactory
对象。
第 177-183 行:
public void set(Object value) throws LoadException {
...
Class<?> type = this.value.getClass();
DefaultProperty defaultProperty = type.getAnnotation(DefaultProperty.class);
if (defaultProperty == null) {
throw constructLoadException("Element does not define a default property.");
}
getProperties().put(defaultProperty.value(), value);
}
本来以为defaultProperty.value()
应该是"nestedCellValueFactory"
,然后赋值,但是抛出的异常清楚地表明不是这样的,所以defaultProperty
应该是空。
可以通过检查 Class<?> type
来解释发生了什么:
type: class com.sun.javafx.fxml.builder.ProxyBuilder
所以type
不是你的NestablePropertyValueFactory
class,而是ProxyBuilder
.
现在,如果您检查 class 没有 @DefaultProperty
注释,因此 defaultProperty
为空并抛出异常。
此代理创建于javafx.fxml.JavaFXBuilderFactory::getBuilder
,基于真实类型:
if (scanForConstructorAnnotations(type)) {
builder = new ProxyBuilder(type);
}
但它 returns 代替了 ProxyBuilder
,并且在此过程中 DefaultProperty
注释丢失了。
代理生成器似乎适用于 classes,其构造函数用 @NamedArg
注释,但 不适用于 @DefaultProperty
注释。
虽然这可能是您的 class 的情况,但应该有比简短的异常消息更好的解释。
无论如何,由于构建器在您添加标签并删除默认注释时工作正常,我只考虑删除 @DefaultProperty
.
我正在尝试创建一个用于 FXML 的自定义 JavaFX 元素,但是当 FXMLLoader
尝试解析它时,它会抛出一个异常,指出:
javafx.fxml.LoadException: Element does not define a default property.
但是,经过一些研究,我相信我正确定义了默认值 属性。
如果我包含 nestedCellValueFactory
标签,一切都会按预期进行。
Java
@DefaultProperty("nestedCellValueFactory")
public class NestablePropertyValueFactory<S, T> extends PropertyValueFactory<S, T> {
private ObjectProperty<PropertyValueFactory<?, ?>> nestedCellValueFactory;
public NestablePropertyValueFactory(
@NamedArg("property") String property,
@NamedArg("nestedCellValueFactory") PropertyValueFactory<?, ?> nestedCellValueFactory) {
super(property);
this.nestedCellValueFactory = new SimpleObjectProperty<>(this, "nestedCellValueFactory", nestedCellValueFactory);
}
public final ObjectProperty<PropertyValueFactory<?, ?>> nestedCellValueFactoryProperty() {
return nestedCellValueFactory;
}
public final PropertyValueFactory<?, ?> getNestedCellValueFactory() {
return nestedCellValueFactoryProperty().get();
}
public final void setNestedCellValueFactory(PropertyValueFactory<?, ?> nestedCellValueFactory) {
nestedCellValueFactoryProperty().set(nestedCellValueFactory);
}
}
FXML
<NestablePropertyValueFactory property="outer">
<NestablePropertyValueFactory property="inner">
<PropertyValueFactory property="property"/>
</NestablePropertyValueFactory>
</NestablePropertyValueFactory>
经过一些调试,我找到了错误的可能解释,但遗憾的是没有解决方案。
如果您 运行 没有 <nestedCellValueFactory>
标签,正如您已经报告的那样,您将得到这个例外:
Caused by: javafx.fxml.LoadException: Element does not define a default property.
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2597)
at javafx.fxml.FXMLLoader.access0(FXMLLoader.java:103)
at javafx.fxml.FXMLLoader$Element.set(FXMLLoader.java:180)
at javafx.fxml.FXMLLoader$ValueElement.processEndElement(FXMLLoader.java:790)
at javafx.fxml.FXMLLoader.processEndElement(FXMLLoader.java:2823)
因此,转到 FXMLLoader
源来跟踪异常,您会发现:
第 790 行:
parent.set(value);
,其中parent
是FXMLLoader$InstanceDeclarationElement
的实例,类型为<your.package.name>. NestablePropertyValueFactory
,value
是一个PropertyValueFactory
对象。第 177-183 行:
public void set(Object value) throws LoadException { ... Class<?> type = this.value.getClass(); DefaultProperty defaultProperty = type.getAnnotation(DefaultProperty.class); if (defaultProperty == null) { throw constructLoadException("Element does not define a default property."); } getProperties().put(defaultProperty.value(), value); }
本来以为defaultProperty.value()
应该是"nestedCellValueFactory"
,然后赋值,但是抛出的异常清楚地表明不是这样的,所以defaultProperty
应该是空。
可以通过检查 Class<?> type
来解释发生了什么:
type: class com.sun.javafx.fxml.builder.ProxyBuilder
所以type
不是你的NestablePropertyValueFactory
class,而是ProxyBuilder
.
现在,如果您检查 class 没有 @DefaultProperty
注释,因此 defaultProperty
为空并抛出异常。
此代理创建于javafx.fxml.JavaFXBuilderFactory::getBuilder
,基于真实类型:
if (scanForConstructorAnnotations(type)) {
builder = new ProxyBuilder(type);
}
但它 returns 代替了 ProxyBuilder
,并且在此过程中 DefaultProperty
注释丢失了。
代理生成器似乎适用于 classes,其构造函数用 @NamedArg
注释,但 不适用于 @DefaultProperty
注释。
虽然这可能是您的 class 的情况,但应该有比简短的异常消息更好的解释。
无论如何,由于构建器在您添加标签并删除默认注释时工作正常,我只考虑删除 @DefaultProperty
.