JavaFXML创建不扩展节点的自定义标记元素

问题描述 投票:0回答:2

我想为我的tag文件创建自定义element / fxml,但我不希望此元素被强制从PaneButtonTextField等继承。 。是否有一些可以在我的自定义元素中实现的接口,需要我实现让我们说的fx()方法,该方法需要返回应该在Node中呈现的Region / Scene元素。我的意思是如果可能出现以下情况?

public class CustomElement implements SOME_FXML_INTERFACE {

    private String myArg;

    public CustomElement(@NamedArg("myArg") myArg) {
        this.myArg = myArg;
    }

    // method that is required to be implemented by SOME_FXML_INTERFACE
    // this method retuns some GUI element which actually needs to be rendered in the Scene
    @Override
    public Object fx() {
        return new TextField(myArg);
    }

}


<HBox>
    <CustomElement myArg="some_argument"/>
</HBox>

所有这些,使我可以有CustomElement可以在构造器中接受自定义参数。

java javafx javafx-8 javafx-2 fxml
2个回答
0
投票

您可以创建任意对象,但是工厂对象只能由支持该对象的节点使用。 (从技术上讲,您可以执行此操作,但是它涉及使用getter每次调用时都返回一个新实例。)但是,您可以例如将您的自定义类用作cellFactory作为ListView

[如果不需要依赖实例方法,但对static工厂方法感到满意,则可以使用fx:factory标记指定创建节点实例的方法,而无需实现任何方法界面来做到这一点:

package my.package;

...

public class CustomElement {

    public static Node fx() {
        return new TextField(myArg);
    }

}
<?import my.package.CustomElement?>
<?import javafx.scene.layout.HBox?>

<HBox xmlns:fx="http://javafx.com/fxml">
    <children>
        <CustomElement fx:factory="fx" />
    </children>
</HBox>

Introduction to FXML中提供了更多信息,>

BTW:如果您的类具有不带任何参数的public构造函数,则只需在fxml中添加具有该类名称的元素即可创建该类的实例。例如。加载时,以下fxml结果为ArrayList;但是,您可以使用这些实例的方式受到限制;

<?import java.util.ArrayList?>

<ArrayList />

0
投票

以及使用工厂方法,如described by fabian,您可以重新调整构建器机制的用途。与<fx:factory>(仅限于无参数的static方法)一样,用法也有所限制。但是,这是一个示例工厂/生成器,它根据是否设置了TextField标志来创建Labeleditable

package org.jamesd.examples.fxmlfactory;

import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.util.Builder;

public class Factory implements Builder<Node> {

    private String text = "" ;
    private boolean editable = false ;



    public String getText() {
        return text;
    }



    public void setText(String text) {
        this.text = text;
    }



    public boolean isEditable() {
        return editable;
    }



    public void setEditable(boolean editable) {
        this.editable = editable;
    }



    @Override
    public Node build() {
        if (editable) {
            return new TextField(text);
        } else {
            return new Label(text);
        }
    }


}
© www.soinside.com 2019 - 2024. All rights reserved.