我试图用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,在我的1600 4K宽屏幕上是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?
在这里:binding
我不明白在哪种情况下我可以使用表达式语言,有规范吗?
编辑:我获得了一个指向javafx-8文档的链接,并删除了我对javaFX-2的过时评论。
发布于 2020-01-07 13:46:26
太晚了,但这可能对某人有帮助。当您在一个<Double fx:id="width" fx:value="300"/>块中使用<fx:define>时,FMXLLoader返回声明的类型Double (在本例中为Double),并尝试调用方法Double.valueOf("300"),这是因为这个调用返回一个值为300的Double对象。使用<Double fx:id="width" fx:value="${300*m.dp}"/>时,将引发NumberFormatException,因为"${300*m.dp}“值不表示有效的双值。
FXMLLoader只在类型可观察时计算以"${“开头的表达式。为了将一个值绑定到FXML中的另一个值,这两个值都应该是可观察的属性。在这种情况下,可以向Measurement类添加以下属性:
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}" />注意: IMHO,我不认为您需要使Measurement类可实例化。在每个FXML文件中重复相同的度量并创建一个新实例是没有意义的。另一种解决方案是具有私有构造函数的类,该类保存静态属性,并通过调用<fx:factory>或<fx:constant>在FXML中使用。
https://stackoverflow.com/questions/37854318
复制相似问题