使用@DefaultProperty时,“元素不定义默认属性”

时间:2017-04-17 18:57:14

标签: java javafx fxml

我正在尝试创建一个用于FXML的自定义JavaFX元素,但是当FXMLLoader尝试解析它时,它会抛出一个异常,指出:

  

javafx.fxml.LoadException:元素未定义默认属性。

然而,在做了一些研究之后,我相信我正确地定义了默认属性。

如果我添加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>

1 个答案:

答案 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);,其中parentFXMLLoader$InstanceDeclarationElement的实例,类型为<your.package.name>. NestablePropertyValueFactoryvalue为{{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