【问题标题】:JavaFX access controller's variables from Scene Builder来自 Scene Builder 的 JavaFX 访问控制器变量
【发布时间】:2013-05-20 23:29:25
【问题描述】:

如果我声明类似

@FXML
private final static double PREF_SPACING = 10d;

@FXML
private Insets insets = new Insets(10d);

在控制器类中, 有没有办法在 Scene Builder 中使用它们的值?

当我想改变值时,我想改变 它只有一次,在控制器类中。

【问题讨论】:

    标签: javafx-2 scenebuilder


    【解决方案1】:

    初步答案 我还没有尝试过以下所有技术,但这似乎是您阅读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 的 Builder)。

    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:definefx:constant 表示法的fxml 文件,以及(可能)使用引用表达式$i.insets。 SceneBuilder 可能没有任何 UI 允许您从 SceneBuilder 应用程序中编辑值,因此如果您希望使用这些元素,您可能需要手动编辑与 fx:definefx:constant 元素相关的 fxml 文件部分结构。

    在此mailing list post on designing resolution independent units in FXML 中有一个使用fx:define 元素的可执行示例。

    一般来说,我认为在维护 fxml 和 java 代码之间的这种依赖关系时我会有点谨慎。正如 scottb 所建议的那样,在控制器 initialize 方法的上下文中,在纯 Java 代码中做更多此类事情可能更谨慎。

    【讨论】:

    • 我觉得这个答案更完整。
    • @jewelsea 也谢谢你!我的想法是找到在不同容器上使用相同值而无需显式 fxml 编码的最快方法。
    【解决方案2】:

    @FXML 注释使您定义的名称 (fx:id) 的 JavaFX 对象能够在从 fxml 标记加载场景图时将其引用反射性地注入到控制器对象的非公共字段中。

    据我所知,这是一种单向操作。没有规定在加载过程中将控制器对象中的命名静态类变量注入场景图中。

    您可以通过在控制器对象的类中定义要设置为类变量的值,然后在 initialize() 中以编程方式(而不是在标记中)设置适当的对象属性,来完成与您所要求的非常相似的事情控制器对象的方法。

    在场景图加载完成后(因此所有 GUI 对象都将被实例化)但在控制权返回到应用程序的调用代码之前调用(如果存在)方法。

    【讨论】:

    • 感谢您的精彩解释!
    猜你喜欢
    • 2013-09-22
    • 2015-03-01
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    • 2015-04-18
    • 2019-08-08
    • 2014-11-02
    • 2016-07-27
    相关资源
    最近更新 更多