簡體   English   中英

JavaFX:是否可以在“fx:define”中使用可變分辨率

[英]JavaFX: Is it possible to use variable resolution in “fx:define”

我正在嘗試使用 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 ();
  }


}

實際上,我不清楚可以使用哪些表達式以及在哪里可以使用,我在這里看到很多答案: 是否可以在 FXML 中使用算術表達式?

此處: 在 JavaFX 中綁定字體大小?

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

我不明白在哪種情況下我可以使用表達式語言,是否有規范?

編輯:我添加了一個指向 javafx-8 文檔的鏈接,並刪除了我對 javaFX-2 的過時評論

太晚了但這可能對某人有幫助。 當您在<fx:define>塊內使用<Double fx:id="width" fx:value="300"/> ,FMXLLoader 使用聲明的類型,在本例中為Double ,並嘗試調用方法Double.valueOf("300")並且這有效,因為此調用返回值為 300 的Double對象。當您使用<Double fx:id="width" fx:value="${300*m.dp}"/> ,由於值“${300*m.dp}”不代表有效的雙精度值,因此將拋出NumberFormatException

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}" />

注意:恕我直言,我認為您不需要使Measurement類可實例化。 重復相同的措施並在每個 FXML 文件中創建新實例沒有任何意義。 另一種解決方案是具有私有構造函數的類,該類包含靜態屬性並通過調用<fx:factory><fx:constant>在 FXML 中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM