如何将子组件和新属性添加到自定义JavaFX控件?

Eug*_*ene 4 java custom-component javafx-2

我想创建一个新的JavaFX组件并在FXML中使用它.如何定义此组件的使用可能性和子类型?有没有办法为这个组件创建我自己的atrributes?例如,这就是我想要的:

<MyNewComponent specificAttribute="...">
   <children>
      <SpecificChildren></SpecificChildren>
   </children>
</MyNewComponent>
Run Code Online (Sandbox Code Playgroud)

Ben*_*ale 7

当您设置属性的值或在FXML中指定子值时,您基本上只是在对象上设置属性.通常,属性用于简单标量值,嵌套值用于设置更复杂的值.

当FXML解析器遇到小写属性或标记时,它假定该值是属性并将尝试在特定对象上设置它.

例如,考虑一个从类派生的自定义类,Parent并重写该getChildren()方法,使其成为控件公共API的一部分.

public class MyNewComponent extends Parent {

    @Override
    public ObservableList<Node> getChildren() {
        return super.getChildren();
    }
}
Run Code Online (Sandbox Code Playgroud)

您现在应该可以在FXML中将其他控件直接添加到自定义控件中.

<MyNewComponent>
    <children>
        <SpecificChildren></SpecificChildren>
    <children>
</MyNewComponent> 
Run Code Online (Sandbox Code Playgroud)

这在概念上类似于以下Java代码:

myNewComponent.getChildren().add(new SpecificChildren());
Run Code Online (Sandbox Code Playgroud)

您可以通过使用如下DefaultProperty注释修饰自定义控件类来进一步改进:

@DefaultProperty(value = "children")
public class MyNewComponent extends Parent {
Run Code Online (Sandbox Code Playgroud)

这允许你省略 <Children></Children>标记,以便您的FXML可以更新为这样.

<MyNewComponent>
    <SpecificChildren></SpecificChildren>
</MyNewComponent>
Run Code Online (Sandbox Code Playgroud)

请注意,这会将控件添加到场景图中,但实际上可能无法将控件显示在您想要的位置,因为您还没有告诉它如何执行此操作(您必须为某些布局方法提供实现或从已经有布局逻辑的类,如VBox).

同样,属性可以这样定义.

@DefaultProperty(value = "children")
public class MyNewComponent extends Parent {

    @Override
    public ObservableList<Node> getChildren() {
        return super.getChildren();
    }

    public String setSpecificAttribute(String str) {
        // Do something here...
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在你的FXML中:

<MyNewComponent specificAttribute = "ABC123">
Run Code Online (Sandbox Code Playgroud)

这在概念上类似于:

myNewComponent.setSpecificAttribute("ABC123");
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅官方FXML参考,因为上述建议有一些例外情况,具体取决于您尝试设置的值的类型,并且可能需要一些额外的代码才能使其正常工作.