Java &引用;元素未定义默认属性";当使用@DefaultProperty时

Java &引用;元素未定义默认属性";当使用@DefaultProperty时,java,javafx,fxml,Java,Javafx,Fxml,我正在尝试创建一个自定义JavaFX元素以在FXML中使用,但是当FXMLLoader尝试解析它时,它抛出一个异常,该异常声明: javafx.fxml.LoadException:元素未定义默认属性 然而,在做了一些研究之后,我相信我正确地定义了默认属性 如果我包括nestedCellValueFactory标记,一切都会正常工作 JAVA @DefaultProperty(“nestedCellValueFactory”) 公共类NestablePropertyValueFactory扩展了

我正在尝试创建一个自定义JavaFX元素以在FXML中使用,但是当
FXMLLoader
尝试解析它时,它抛出一个异常,该异常声明:

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

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

如果我包括
nestedCellValueFactory
标记,一切都会正常工作

JAVA
@DefaultProperty(“nestedCellValueFactory”)
公共类NestablePropertyValueFactory扩展了PropertyValueFactory{
private ObjectProperty>nestedCellValueFactoryProperty(){
返回nestedCellValueFactory;
}
公共最终属性ValueFactory getNestedCellValueFactory(){
返回nestedCellValueFactoryProperty().get();
}
公共最终作废设置nestedCellValueFactory(PropertyValueFactory nestedCellValueFactory){
nestedCellValueFactoryProperty().set(nestedCellValueFactory);
}
}
FXML
经过一些调试后,我对错误有了可能的解释,但遗憾的是没有解决方法

如果您在没有
标记的情况下运行,正如您已经报告的那样,您将得到以下异常:

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)
因此,转到
fxmloader
源以跟踪异常,您将发现:

  • 第790行:
    parent.set(值)
    ,其中,
    parent
    是类型为
    FXMLLoader$InstanceDecrationElement
    的实例。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);
    }
    
    因此,
    type
    不是您的
    NestablePropertyValueFactory
    类,而是一个
    ProxyBuilder

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

    此代理是在
    javafx.fxml.JavaFXBuilderFactory::getBuilder
    中创建的,基于实际类型:

        if (scanForConstructorAnnotations(type)) {
            builder = new ProxyBuilder(type);
        }
    
    但是它会返回
    ProxyBuilder
    ,在这个过程中,
    DefaultProperty
    注释会丢失

    代理生成器似乎适用于具有用
    @NamedArg
    注释的构造函数的类,但不适用于
    @DefaultProperty
    注释

    虽然您的类可能就是这种情况,但应该有比短异常消息更好的解释


    无论如何,当添加标记和删除默认注释时,构造函数工作正常,我只考虑删除<代码> @ Debug属性。但是IntellJ一直建议我删除元素,因为它是默认属性,所以我必须相信我至少在某些方面走上了正确的道路。我最初是用JDK 1.8.0_92运行此功能的,但我切换到1.8.0_121并得到了相同的结果。感谢您非常详细的回复!这完全有道理。我可以接受指定属性名称——我只是想知道为什么这不起作用,知道我将来可能会再次尝试使用它。再次感谢您的回复!

    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);
    }
    
     type: class com.sun.javafx.fxml.builder.ProxyBuilder
    
        if (scanForConstructorAnnotations(type)) {
            builder = new ProxyBuilder(type);
        }