Java 您能否将变量传递给FXML中的Insets?

Java 您能否将变量传递给FXML中的Insets?,java,fxml,Java,Fxml,我正在做一些工作,需要基于标量值为元素设置不同的值。我的工作是在一个名为Sizer的类中找到标量值,该类使用一个名为getScalar()的方法,该方法返回一个double。下面是我现在拥有的部分FXML <VBox id="mainWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" x

我正在做一些工作,需要基于标量值为元素设置不同的值。我的工作是在一个名为Sizer的类中找到标量值,该类使用一个名为getScalar()的方法,该方法返回一个double。下面是我现在拥有的部分FXML

<VBox id="mainWindow" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller">
   <fx:define>
      <Sizer fx:id="SCALAR" fx:factory="getScalar"/>
   </fx:define>
   <children>
     <HBox alignment="CENTER_LEFT">
        <children>
           <Label fx:id="titleLabel" text="Label" HBox.hgrow="ALWAYS" />
           <HBox fx:id="titleBar" HBox.hgrow="ALWAYS" />
        </children>
        <padding>
           <!-- This part DOESN'T work at runtime -->
           <Insets left="${SCALAR * 10.0}" right="${SCALAR * 10.0}" top="${SCALAR * 5.0}" />
        </padding>
     </HBox>
     <!-- This part DOES work at runtime -->
     <Separator prefWidth="${SCALAR * 200.0}" />
  </children>
</Vbox>
我的理解

您可以通过定义块创建这些已定义的对象,然后通过表达式绑定和变量解析在其他属性中引用它们,但不知何故,我无法使用插入来实现这一点。我发现的唯一一件事是“prefWidth”有一个二传,而“left”或其他带插图的位置有一个getter。我想它可能会在绑定到似乎没有setter的对象时出现问题

任何帮助都将不胜感激,因为我对FXML不太了解,而且我来自一个JavaFX世界,在那里这要容易得多

编辑 下面是Sizer类的内容

public static Toolkit getToolKit() {
    return Toolkit.getDefaultToolkit();
}
public static Dimension getScreenSize() {
    return getToolKit().getScreenSize();
}
public static int getPercentOfHeight(double percent) {
    return (int)(getScreenSize().getHeight() * percent / 100.0);
}
public static int getPercentOfWidth(double percent) {
    return (int)(getScreenSize().getWidth() * percent / 100.0);
}
public static double getScaleFactor() {
    if ((int) getScreenSize().getHeight() > 1800) return 2.0;    //4K
    else if ((int)getScreenSize().getHeight() > 1260) return 1.33; //1440p
    else if ((int)getScreenSize().getHeight() > 900) return 1.0;     //1080p
    else return 0.667;                                   //720p
}

${}
语法用于创建一个属性,该属性反过来用于将
属性
绑定到生成的
可观察值
。代码的问题是
Insets
没有将其状态公开为
属性
实例。最重要的是,
Insets
类是不可变的,这意味着状态是通过一个构造函数设置的,两个构造函数只接受
双参数。您不能将表达式绑定的结果作为
double
传递,并且
fxmloader
在创建
Insets
实例时没有“巧妙地”提取当前值

据我所知,您希望将插入的
的每一侧乘以一个
double
值,这只需要发生一次(即不需要随时间更新值)。在这种情况下,一种解决方案是将
Insets子类化,并为标量参数的每个构造函数“添加一个参数”

package.com.example;
导入javafx.beans.NamedArg;
导入javafx.geometry.Insets;
公共类伸缩集扩展插入集{
公共刻度集(@NamedArg(value=“scale”,defaultValue=“1”)双刻度,
@NamedArg(“顶部”)双顶部,@NamedArg(“右侧”)右侧,
@NamedArg(“下”)双底,@NamedArg(“左”)双左){
超级(比例*顶部、比例*右侧、比例*底部、比例*左侧);
}
公共刻度集(@NamedArg(value=“scale”,defaultValue=“1”)双刻度,
@NamedArg(“topRightBottomLeft”)双右上下左){
超级(比例*上右下左);
}
}
这将允许您在FXML文件中使用以下内容:



请注意,FXML还支持:

标记允许调用方将脚本代码导入FXML文件或将脚本嵌入FXML文件中。可以使用任何JVM脚本语言,包括JavaScript、Groovy和Clojure等。脚本代码通常用于直接在标记或关联的源文件中定义事件处理程序,因为事件处理程序通常可以用类型更松散的脚本语言编写,而不是用静态类型语言(如Java)编写

我以前从未在FXML中使用过脚本,现在不知道如何在示例中使用它。我只想说,你可以随意处理它,但我不知道脚本是否是一个可行的解决方案


与您的问题无关,但您似乎正在使用AWT类来获取屏幕尺寸。JavaFX为此提供了自己的API:。您可以使用:

Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();

获取主屏幕的尺寸。要获得整个屏幕的尺寸,而不仅仅是视觉区域,请使用
getBounds()
而不是
getVisualBounds()

${}
语法来创建一个属性,该属性反过来用于将
属性
绑定到生成的
observeValue
。代码的问题是
Insets
没有将其状态公开为
属性
实例。最重要的是,
Insets
类是不可变的,这意味着状态是通过一个构造函数设置的,两个构造函数只接受
双参数。您不能将表达式绑定的结果作为
double
传递,并且
fxmloader
在创建
Insets
实例时没有“巧妙地”提取当前值

据我所知,您希望将插入的
的每一侧乘以一个
double
值,这只需要发生一次(即不需要随时间更新值)。在这种情况下,一种解决方案是将
Insets子类化,并为标量参数的每个构造函数“添加一个参数”

package.com.example;
导入javafx.beans.NamedArg;
导入javafx.geometry.Insets;
公共类伸缩集扩展插入集{
公共刻度集(@NamedArg(value=“scale”,defaultValue=“1”)双刻度,
@NamedArg(“顶部”)双顶部,@NamedArg(“右侧”)右侧,
@NamedArg(“下”)双底,@NamedArg(“左”)双左){
超级(比例*顶部、比例*右侧、比例*底部、比例*左侧);
}
公共刻度集(@NamedArg(value=“scale”,defaultValue=“1”)双刻度,
@NamedArg(“topRightBottomLeft”)双右上下左){
超级(比例*上右下左);
}
}
这将允许您在FXML文件中使用以下内容:



请注意,FXML还支持:

标记允许调用方将脚本代码导入FXML文件或将脚本嵌入FXML文件中。可以使用任何JVM脚本语言,包括JavaScript、Groovy和Clojure
Rectangle2D visualBounds = Screen.getPrimary().getVisualBounds();