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

我想为我的tag文件创建自定义element / fxml,但是我不希望这个元素被强制从Pane,{ {1}},Button等。是否有一些可以在我的自定义元素中实现的接口,需要我实现让说TextField的方法,该方法需要返回应该呈现的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> 可以在构造函数中接受自定义参数。

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

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

如果您不需要依赖实例方法,但是对ListView工厂方法感到满意,则可以使用static标签指定一种方法来创建节点实例,然后执行不需要实现任何接口即可做到这一点:

fx:factory
package my.package;

...

public class CustomElement {

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

}

更多信息,请访问Introduction to FXML

顺便说一句:如果您的类有一个不带任何参数的<?import my.package.CustomElement?> <?import javafx.scene.layout.HBox?> <HBox xmlns:fx="http://javafx.com/fxml"> <children> <CustomElement fx:factory="fx" /> </children> </HBox> 构造函数,则只需在fxml中添加一个具有该类名称的元素即可创建该类的实例。例如。以下fxml在加载时产生public;但是,使用这些实例的方式受到限制;

ArrayList
,

除了使用工厂方法(如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);
        }
    }


}

这是一个使用此格式的FXML文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.layout.BorderPane ?>
<?import javafx.scene.layout.HBox ?>
<?import javafx.scene.Node ?>


<BorderPane xmlns="http://javafx.com/javafx/11.0.1"
    xmlns:fx="http://javafx.com/fxml/1">

    <center>
        <HBox spacing="5">
            <Node text="Hello" editable="false" />
            <Node text="Name" editable="true" />
        </HBox>
    </center>
</BorderPane>

要使FXMLLoader了解您的构建器,您必须指定一个用于其的类。在这里,我们可以将其用于Node(但此要求有点限制性,因为您实际上将仅限于一个生成器)。为此,您可以创建一个BuilderFactory实现:

package org.jamesd.examples.fxmlfactory;

import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Node;
import javafx.util.Builder;
import javafx.util.BuilderFactory;

public class NodeBuilderFactory implements BuilderFactory{

    private final JavaFXBuilderFactory defaultFactory = new JavaFXBuilderFactory();

    public Builder<?> getBuilder(Class<?> type) {
        if (type == Node.class) {
            return new Factory();
        }
        return defaultFactory.getBuilder(type);
    }

}

,然后向FXMLLoader注册:

package org.jamesd.examples.fxmlfactory;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class App extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {

        FXMLLoader loader = new FXMLLoader(getClass().getResource("Example.fxml"));
        loader.setBuilderFactory(new NodeBuilderFactory());
        Parent root = loader.load();
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        Application.launch(args);
    }

}
本文链接:https://www.f2er.com/2650072.html

大家都在问