除了使用fabian 所描述的工厂方法外,您还可以重新利用构建器机制来执行此操作。与 一样<fx:factory>,它仅限于static没有参数的方法,用法有点受限。TextField但是,这是一个创建 a或 a的示例工厂/构建器Label,具体取决于是否editable设置了标志:
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);
}
}