gpt4 book ai didi

JavaFX : Is it possible to use variable resolution in "fx:define"

转载 作者:行者123 更新时间:2023-12-04 21:36:00 33 4
gpt4 key购买 nike

我正在尝试使用 fx:define 定义动态评估变量,但我无法从另一个变量中获得要评估的变量,我不知道这是否可能?

<GridPane hgap="${10*m.dp}" vgap="${10*m.dp}" xmlns="http://javafx.com/javafx/8.0.51" xmlns:fx="http://javafx.com/fxml/1">
<fx:define>
<Measurement fx:id="m" />
<!-- This works, but is not what I need -->
<Double fx:id="width" fx:value="300" />
<!-- This doesn't work -->
<!-- <Double fx:id="width" fx:value="${300*m.dp}" /> -->
</fx:define>
<padding>
<Insets bottom="$width" left="$width" right="$width" top="$width" />
</padding>
<Text text="hello" />
<Button GridPane.rowIndex="1" text="button" prefWidth="${300*m.dp}" />
<Button GridPane.rowIndex="2" text="button2" prefWidth="$width" />
</GridPane>

我想要的是从我计算的 dp 计算宽度(密度独立像素 - 在高清屏幕中为 1,在 4K 屏幕中为 2,在我的 1600px 宽度屏幕上为 0.xx)。我想要的“宽度”变量将在我的真实案例中用于很多组件,这就是我想要一个变量的原因——为了简洁。

运行它的java代码
public class Measurement {
private double dp;

public Measurement(){
Screen primary = Screen.getPrimary();
dp=primary.getBounds().getWidth()/1920;
}

/**
* Equivalent of 1 px in 1920.
*/
public double getDp(){
return dp;
}

public void setDp (double dp) {
this.dp = dp;
}

}
public class MApplication extends Application {
public static void main (String[] args) {
launch (args);
}

@Override
public void start (Stage primaryStage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader();
Parent root = fxmlLoader.load(getClass().getResource("index.fxml").openStream());
Scene scene = new Scene(root, 300, 275);
primaryStage.setMaximized(true);
primaryStage.setScene(scene);
primaryStage.show ();
}


}

实际上,我不清楚可以在哪里使用表达式,我在这里看到了很多答案: Is it possible to use arithmetic expression in FXML?

这里: Bind Font Size in JavaFX?

和这里:
http://docs.oracle.com/javase/8/javafx/api/javafx/fxml/doc-files/introduction_to_fxml.html#expression_binding

我不明白在什么情况下可以使用表达语言,有规范吗?

已编辑:我添加了指向 javafx-8 文档的链接,并删除了对 javaFX-2 的过时评论

最佳答案

太晚了,但这可能对某人有帮助。当您使用 <Double fx:id="width" fx:value="300"/><fx:define> 内 block ,FMXLLoader 进入声明的类型,Double在这种情况下,并尝试调用方法 Double.valueOf("300")这有效,因为此调用返回 Double值为 300 的对象。
当您使用 <Double fx:id="width" fx:value="${300*m.dp}"/> , 一个 NumberFormatException将被抛出,因为值 "${300*m.dp}"不代表有效的 double 值。

FXMLLoader 仅在类型可观察时计算以“${”开头的表达式。
为了在 FXML 中将一个值绑定(bind)到另一个值,它们都应该是可观察的属性。在您的情况下,您可以将以下属性添加到 Measurement类(class):

public class Measurement {
public final DoubleProperty dp = new SimpleDoubleProperty();

public Measurement() {
Screen primary = Screen.getPrimary();
dp.set(primary.getBounds().getWidth() / 1920.0);
}

public double getDp() {
return dp.get();
}

public void setDp(double dp) {
this.dp.set(dp);
}

public final DoubleProperty widthProperty() {
if (width == null) {
width = new SimpleDoubleProperty();
width.bind(dp.multiply(300.0));
}
return width;
}

private DoubleProperty width;

public final double getWidth() {
return width == null ? 0 : width.get();
}
}

然后在您的 FXML 中像这样使用它:

<fx:define>
<Measurement fx:id="measurement"/>
</fx:define>
<Button prefWidth="${measurement.width}" />

注:恕我直言,我认为您不需要制作 Measurement类可实例化。重复相同的措施并在每个 FXML 文件中创建新实例是没有意义的。另一种解决方案是具有私有(private)构造函数的类,该构造函数包含静态属性并通过调用 <fx:factory> 在 FXML 中使用。或 <fx:constant> .

关于JavaFX : Is it possible to use variable resolution in "fx:define",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37854318/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com