我正在尝试创建一个用于FXML的自定义JavaFX元素,但是当FXMLLoader
尝试解析它时,它会抛出一个异常,指出:
javafx.fxml.LoadException:元素未定义默认属性。
然而,在做了一些研究之后,我相信我正确地定义了默认属性。
如果我添加nestedCellValueFactory
标记,则一切都按预期工作。
@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);
}
}
<NestablePropertyValueFactory property="outer">
<NestablePropertyValueFactory property="inner">
<PropertyValueFactory property="property"/>
</NestablePropertyValueFactory>
</NestablePropertyValueFactory>
答案 0 :(得分:3)
经过一些调试后,我对错误有了可能的解释,但遗憾的是没有解决方案。
如果您在没有<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.access$100(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
为{{1}对象。
第177-183行:
PropertyValueFactory
可以预期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"
应为null。
通过检查defaultProperty
:
Class<?> type
因此 type: class com.sun.javafx.fxml.builder.ProxyBuilder
不是您的type
类,而是NestablePropertyValueFactory
。
现在,如果您检查该类没有ProxyBuilder
注释,那么@DefaultProperty
为空并抛出异常。
此代理基于实际类型在defaultProperty
中创建:
javafx.fxml.JavaFXBuilderFactory::getBuilder
但它会返回 if (scanForConstructorAnnotations(type)) {
builder = new ProxyBuilder(type);
}
,而在此过程中ProxyBuilder
注释会丢失。
代理构建器似乎适用于带有DefaultProperty
注释的构造函数的类,但@NamedArg
注释的不是。
虽然这可能是你班级的情况,但应该有比短期异常消息更好的解释。
无论如何,由于构建器在添加标签并删除默认注释时工作正常,我只考虑删除@DefaultProperty
。