I am doing some work that requires me to have different values for elements based on a scalar value. I have the work to come up with the scalar value in a class called Sizer with a method called getScalar() which returns a double. Below is the partial FXML that I have right now.
<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>
In this code, if I take out the Insets references and just make those values 10.0, 5.0, etc, it works at runtime and my dialog appears. The 'prefWidth' setting using SCALAR seems to be working fine, but when I add in the reference to the Insets values it throws and error pointing to the line with Insets on it.
javafx.fxml.LoadException: Cannot bind to untyped object.
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2621)
at javafx.fxml.FXMLLoader.access$100(FXMLLoader.java:105)
at javafx.fxml.FXMLLoader$Element.processPropertyAttribute(FXMLLoader.java:306)
at javafx.fxml.FXMLLoader$Element.processInstancePropertyAttributes(FXMLLoader.java:242)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:757)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
My Understanding
You are able to create these defined objects through define blocks and then reference them in other attributes by way of expression binding and variable resolution, but somehow I cannot do this with Insets. The only thing that I've found is that 'prefWidth' has a setter taking a double whereas 'left' or other positions with Insets have getters. I thought maybe it could have issues with binding to an object that doesn't appear to have a setter.
Any help would be appreciated as I'm not that knowledgable about FXML, and I come from a JavaFX world where this is much easier.
EDIT Below is the contents of the Sizer class
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
}