如果我宣布类似
的内容@FXML
private final static double PREF_SPACING = 10d;
或
@FXML
private Insets insets = new Insets(10d);
在控制器类中, 有没有办法在Scene Builder中使用它们的值?
当我想改变价值时,我想改变 它只在控制器类中一次。
答案 0 :(得分:4)
初步答案 我还没有尝试过下面的所有技术,但是看起来你通过阅读documentation就可以了。如果我有时间,我会稍后尝试一下并用结果更新这个答案(或者其他人可以这样做并发布一个新的答案或编辑这个答案来创建一个明确的答案)。我现在只想发布一些内容,指出我认为是正确的方向。
如果以下内容不符合您的要求,请在问题中添加一些细节,以全面描述您的需求。
请勿在此处使用@FXML
注释。 @FXML
用于将标记中的值注入控制器,而不是相反。
对于你的第一个例子,它是一个常量,假设你的控制器类是:
class MyControllerType {
public final static double PREF_SPACING = 10d;
}
然后在你的fxml中,引用常量:
<?import MyControllerType?>
...
<VBox>
<spacing><MyControllerType fx:constant="PREF_SPACING"/></spacing>
</VBox>
对于第二个不是常量或SceneGraph的一部分的样本,可以使用fx:define
元素来实例化该类的实例。请注意,您无法直接从FXML实例化Insets类,因为它没有构建器类也没有零长度构造函数。所以你可以做的是为信息创建另一个占位符类,并在FXML中实例化对它的引用(或者你可以创建一个FXML可以用来实例化Insets的构建器)。
class InsetsHolder {
private Insets insets = new Insets(10d);
public Insets getInsets();
}
<?import InsetsHolder?>
<fx:define>
<InsetsHolder fx:id="i"/>
</fx:define>
<VBox>
<Button text="Click Me!" VBox.margin="$i.insets"/>
</VBox>
SceneBuilder应该能够读取使用fx:define
和fx:constant
表示法的fxml文件,以及(可能)使用引用表达式$i.insets
。 SceneBuilder可能没有任何UI允许您编辑SceneBuilder应用程序中的值,因此如果您希望,您可能需要手动编辑与fx:define
和fx:constant
元素相关的fxml文件部分利用这些结构。
在此mailing list post on designing resolution independent units in FXML中有一个使用fx:define
元素的可执行示例。
一般来说,我认为在fxml和java代码之间保持这种依赖关系我会有点谨慎。在scottb建议的控制器initialize
方法的上下文中,在纯Java代码中做更多这类东西可能更为谨慎。
答案 1 :(得分:2)
@FXML注释使得您定义的名称(fx:id)的JavaFX对象能够将其引用反射注入到控制器对象的非公共字段中,因为场景图是从fxml标记加载的。
据我所知,这是一种单向操作。在加载期间,没有规定在注入到场景图中的控制器对象中命名静态类变量。
通过在控制器对象的类中定义要设置为类变量的值,然后在initialize()中以编程方式(而不是在标记中)设置适当的对象属性,可以完成与请求非常相似的操作控制器对象的方法。
在加载场景图完成后调用initialize()方法(如果它存在)(因此所有GUI对象都将被实例化)但在控制返回到应用程序的调用代码之前。