组件构造函数参数 fxml javafx
Component constructor arguments fxml javafx
首先,我给你我的代码。
组件
public class Schuiver extends VBox{
private final SchuiverCompanion companion;
public Schuiver(String text) {
try {
FXMLLoader loader = new FXMLLoader(
Schuiver.class.getResource("nuleenschuiver.fxml"));
loader.setRoot(this);
this.companion = new SchuiverCompanion();
loader.setController(companion);
companion.setText(text);
loader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
}
组件控制器
public class SchuiverCompanion {
public TextField kleurveld;
public Label titel;
public Slider schuiver;
public void initialize() {
kleurveld.textProperty().bindBidirectional(schuiver.valueProperty(),
new NumberStringConverter());
}
public void setText(String text){
titel.setText(text);
}
}
COMPONENTFXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<fx:root fx:id="vbox" minHeight="-1.0" prefHeight="-1.0" prefWidth="-1.0" spacing="5.0" type="javafx.scene.layout.VBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kleurenkiezer.SchuiverCompanion">
<children>
<Label fx:id="titel" alignment="TOP_LEFT" text="Hier een titel" />
<HBox prefHeight="44.0" prefWidth="299.0">
<children>
<Slider fx:id="schuiver" prefHeight="14.0" prefWidth="215.0" />
<TextField fx:id="kleurveld" prefHeight="25.0" prefWidth="76.0" />
</children>
</HBox>
</children>
</fx:root>
如您所见,我的组件请求一个将放置在标签中的字符串,
问题是,如果您像这样创建 objects,则无法在 fxml 文件中传递参数:
<Schuiver fx:id="red" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
<Schuiver fx:id="blue" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
所以我的问题是,如果我使用我的组件启动程序,我该如何更改标签 'Titel' 的文本?标题应该像 fix:id.
在 JavaFX 8 中,您可以通过使用 @NamedArg(...)
:
注释构造函数参数来做到这一点
public class Schuiver extends VBox{
private final SchuiverCompanion companion;
public Schuiver(@NamedArg("text") String text) {
// ...
}
}
然后就可以使用FXML中的参数了:
<Schuiver fx:id="red" text="red" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
<Schuiver fx:id="blue" GridPane.columnIndex="1" GridPane.rowIndex="1">
<text>
<String fx:value="blue" />
</text>
</Schuiver>
概览
尽管 OP 已经选择了一个最佳答案,但从评论中可以看出有些混乱,并且所选答案没有直接回答他们的问题并且缺少信息,所以我发布了我认为是 full/complete 回答:
在 JavaFX 中创建自定义组件时,如果您想在组件创建时为其提供一个或多个默认值,您不能简单地向使用的默认构造函数添加参数JavaFX 在幕后执行 FXML 加载操作。
为了解决这个难题,我们提供了将参数添加到默认构造函数的能力,前提是它们使用 @NamedArg("name of parameter here") 注释进行注释。这允许在 运行 时以编程方式或通过 FXML 构造自定义组件时为其提供值。
详细信息和示例
自定义组件控制器构造函数
public MyCustomComponent(@NamedArg("foo") String foo) { }
在幕后,JavaFX 认识到组件的构造函数现在有一个用@NamedArg 注释的参数,这将反映在当前使用组件的任何地方。查找或创建 FXML 文档并将您的组件放入文本中。然后您应该能够从 FXML 设置命名参数,并且您的 IDE 的智能感知也应该支持这一点。
通过 FXML 向组件添加值
<MyCustomComponent foo="myStringValue"/>
您可以通过编程方式设置参数:
MyCustomComponent myComp = new MyCustomComponent("myStringValue");
现在,OP 问题的当前选定答案没有提到这一点,但据我所知,您还需要注意一个步骤,否则 none 这将起作用。控制器 class 必须具有与命名参数匹配的 属性。我相信这是在幕后初始化 FXML 所必需的,但我可能是错的。 Java 中的属性,大部分看起来像这样:
private StringProperty foo = new SimpleStringProperty();
public String getFoo()
{
return foo.get();
}
public void setFoo(String value)
{
this.foo.set(value);
}
public StringProperty fooProperty()
{
return foo;
}
结论
我想在这里添加这个,因为之前的答案确实回答了问题,但没有完全回答,虽然看起来 OP 确实能够解决问题,但答案没有提到 OP realized/changed让它工作,因为起初它没有解决问题。我 100% 知道这会按预期运行。
首先,我给你我的代码。
组件
public class Schuiver extends VBox{
private final SchuiverCompanion companion;
public Schuiver(String text) {
try {
FXMLLoader loader = new FXMLLoader(
Schuiver.class.getResource("nuleenschuiver.fxml"));
loader.setRoot(this);
this.companion = new SchuiverCompanion();
loader.setController(companion);
companion.setText(text);
loader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
}
组件控制器
public class SchuiverCompanion {
public TextField kleurveld;
public Label titel;
public Slider schuiver;
public void initialize() {
kleurveld.textProperty().bindBidirectional(schuiver.valueProperty(),
new NumberStringConverter());
}
public void setText(String text){
titel.setText(text);
}
}
COMPONENTFXML
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<fx:root fx:id="vbox" minHeight="-1.0" prefHeight="-1.0" prefWidth="-1.0" spacing="5.0" type="javafx.scene.layout.VBox" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="kleurenkiezer.SchuiverCompanion">
<children>
<Label fx:id="titel" alignment="TOP_LEFT" text="Hier een titel" />
<HBox prefHeight="44.0" prefWidth="299.0">
<children>
<Slider fx:id="schuiver" prefHeight="14.0" prefWidth="215.0" />
<TextField fx:id="kleurveld" prefHeight="25.0" prefWidth="76.0" />
</children>
</HBox>
</children>
</fx:root>
如您所见,我的组件请求一个将放置在标签中的字符串, 问题是,如果您像这样创建 objects,则无法在 fxml 文件中传递参数:
<Schuiver fx:id="red" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
<Schuiver fx:id="blue" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
所以我的问题是,如果我使用我的组件启动程序,我该如何更改标签 'Titel' 的文本?标题应该像 fix:id.
在 JavaFX 8 中,您可以通过使用 @NamedArg(...)
:
public class Schuiver extends VBox{
private final SchuiverCompanion companion;
public Schuiver(@NamedArg("text") String text) {
// ...
}
}
然后就可以使用FXML中的参数了:
<Schuiver fx:id="red" text="red" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
<Schuiver fx:id="blue" GridPane.columnIndex="1" GridPane.rowIndex="1">
<text>
<String fx:value="blue" />
</text>
</Schuiver>
概览
尽管 OP 已经选择了一个最佳答案,但从评论中可以看出有些混乱,并且所选答案没有直接回答他们的问题并且缺少信息,所以我发布了我认为是 full/complete 回答:
在 JavaFX 中创建自定义组件时,如果您想在组件创建时为其提供一个或多个默认值,您不能简单地向使用的默认构造函数添加参数JavaFX 在幕后执行 FXML 加载操作。
为了解决这个难题,我们提供了将参数添加到默认构造函数的能力,前提是它们使用 @NamedArg("name of parameter here") 注释进行注释。这允许在 运行 时以编程方式或通过 FXML 构造自定义组件时为其提供值。
详细信息和示例
自定义组件控制器构造函数
public MyCustomComponent(@NamedArg("foo") String foo) { }
在幕后,JavaFX 认识到组件的构造函数现在有一个用@NamedArg 注释的参数,这将反映在当前使用组件的任何地方。查找或创建 FXML 文档并将您的组件放入文本中。然后您应该能够从 FXML 设置命名参数,并且您的 IDE 的智能感知也应该支持这一点。
通过 FXML 向组件添加值
<MyCustomComponent foo="myStringValue"/>
您可以通过编程方式设置参数:
MyCustomComponent myComp = new MyCustomComponent("myStringValue");
现在,OP 问题的当前选定答案没有提到这一点,但据我所知,您还需要注意一个步骤,否则 none 这将起作用。控制器 class 必须具有与命名参数匹配的 属性。我相信这是在幕后初始化 FXML 所必需的,但我可能是错的。 Java 中的属性,大部分看起来像这样:
private StringProperty foo = new SimpleStringProperty();
public String getFoo()
{
return foo.get();
}
public void setFoo(String value)
{
this.foo.set(value);
}
public StringProperty fooProperty()
{
return foo;
}
结论
我想在这里添加这个,因为之前的答案确实回答了问题,但没有完全回答,虽然看起来 OP 确实能够解决问题,但答案没有提到 OP realized/changed让它工作,因为起初它没有解决问题。我 100% 知道这会按预期运行。