“元素未定义默认属性";使用@DefaultProperty时 [英] "Element does not define a default property" when @DefaultProperty is used

查看:416
本文介绍了“元素未定义默认属性";使用@DefaultProperty时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个自定义JavaFX元素以在FXML中使用,但是当FXMLLoader试图对其进行解析时,它会抛出一个异常,指出:

I am trying to create a custom JavaFX element for use in FXML, but when FXMLLoader tries to parse it, it throws an exception that states:

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

javafx.fxml.LoadException: Element does not define a default property.

但是,在进行了一些研究之后,我相信我正在正确定义默认属性.

However, after doing some research, I believe that I am defining the default property properly.

如果我包含nestedCellValueFactory标记,则一切正常.

If I include the nestedCellValueFactory tags, everything works as expected.

@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>

推荐答案

经过一些调试,我对该错误有可能的解释,但遗憾的是没有解决方案.

After some debugging, I have a possible explanation for the error, but sadly not a solution for it.

如果您运行时没有<nestedCellValueFactory>标记(如您已经报告的那样),则会出现此异常:

If you run without the <nestedCellValueFactory> tags, as you already reported, you will get this exception:

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源以跟踪异常,您将找到:

So going to the FXMLLoader sources to track the exception you will find:

  • 第790行:parent.set(value);,其中parentFXMLLoader$InstanceDeclarationElement的实例,类型为<your.package.name>. NestablePropertyValueFactory,而valuePropertyValueFactory对象.

  • Line 790: parent.set(value);, where parent is an instance of FXMLLoader$InstanceDeclarationElement, with type <your.package.name>. NestablePropertyValueFactory, and value is a PropertyValueFactory object.

第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应该为空.

One could expect that defaultProperty.value() should be "nestedCellValueFactory", and the value will be assigned, but the exception thrown clearly shows that this is not the case, so defaultProperty should be null.

发生什么情况可以通过检查Class<?> type来解释:

What happens can be explained by inspecting Class<?> type:

 type: class com.sun.javafx.fxml.builder.ProxyBuilder

所以type不是您的NestablePropertyValueFactory类,而是一个ProxyBuilder.

So type is not your NestablePropertyValueFactory class, but a ProxyBuilder.

现在,如果您检查该类,则没有@DefaultProperty批注,因此defaultProperty为null并引发异常.

Now, if you check that class there is no @DefaultProperty annotation, hence defaultProperty is null and the exception is thrown.

此代理根据实际类型在javafx.fxml.JavaFXBuilderFactory::getBuilder中创建:

This proxy is created in javafx.fxml.JavaFXBuilderFactory::getBuilder, based on the real type:

    if (scanForConstructorAnnotations(type)) {
        builder = new ProxyBuilder(type);
    }

,但它会返回ProxyBuilder,并且在此过程中,DefaultProperty批注会丢失.

but it returns the ProxyBuilder instead, and in the process the DefaultProperty annotation gets lost.

代理构建器似乎旨在用于带有以@NamedArg注释的构造函数的类,但是对于@DefaultProperty注释的不是的类.

The proxy builder seems intended for classes with constructors annotated with @NamedArg, but not for the @DefaultProperty annotation.

虽然在您的课堂上可能是这种情况,但应该比简短的异常消息更好的解释.

While this could be the case of your class, there should be a better explanation than the short exception message.

无论如何,由于构建器在添加标签并删除默认注释时工作正常,所以我只考虑删除@DefaultProperty.

Anyway, as the builder works fine when you add the tags and remove the default annotation, I would just consider removing @DefaultProperty.

这篇关于“元素未定义默认属性";使用@DefaultProperty时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆