组件构造函数参数 fxml javafx
Posted
技术标签:
【中文标题】组件构造函数参数 fxml javafx【英文标题】:Component constructor arguments fxml javafx 【发布时间】:2015-07-28 05:59:30 【问题描述】:首先,我给你我的代码。
组件
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>
就像你看到我的组件询问一个将被放置在标签中的字符串, 问题是,如果您像这样创建对象,则无法在 fxml 文件中传递参数:
<Schuiver fx:id="red" GridPane.columnIndex="1" GridPane.rowIndex="0"/>
<Schuiver fx:id="blue" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
所以我的问题是,如果我使用我的组件启动程序,如何更改标签“Titel”的文本?标题应该类似于 fix:id。
【问题讨论】:
【参考方案1】:概述
虽然 OP 已经选择了一个最佳答案,但从 cmets 看来,存在一些混淆,并且所选答案没有完全回答他们的问题并且缺少信息,所以我发布了我认为是完整/完整答案的内容:
在 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 问题的当前选择答案没有提到这一点,但据我所知,您还需要处理一个步骤,否则这些都不起作用。控制器类必须具有与命名参数匹配的属性。我相信这是在幕后初始化 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 实现/更改的内容工作,因为起初它没有解决问题。我 100% 知道这将按预期运行。
【讨论】:
【参考方案2】:在 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>
【讨论】:
实际上这给了我错误:此处不允许使用属性。 您在运行时看到该错误吗?还是在您的 IDE 中?如果 IDE 不知道这个用例,我不会感到惊讶。 我使用 IntelliJ,当我运行它时,我得到这个: 原因:java.lang.RuntimeException:无法创建具有给定属性集的 kleurenkiezer.Schuiver 实例:[标题] 我将文本更改为标题 属性名称 (titel
) 与传递给 @NamedArg
注释的值匹配(即您有 @NamedArg("titel")
?)
是的,我的构造函数 Shuiver 中有它以上是关于组件构造函数参数 fxml javafx的主要内容,如果未能解决你的问题,请参考以下文章
我们啥时候应该为组件实现带有 IContainer 参数的构造函数?