Search code examples
javajavafxpaddingcoerciontype-coercion

How to set FXML "padding" property in one line


I would like to define a button's padding the same way as in C# XAML files. Instead of writing things like:

<Button fx:id="btn1" ...>
    <padding>
        <Insets top="0" right="5" bottom="10" left="5" />
    </padding>
</Button>

<Button fx:id="btn2" ...>
    <padding>
        <Insets topRightBottomLeft="5" />
    </padding>
</Button>

, it would be easier to write:

<Button fx:id="btn1" ... padding="0 5 10 5" />
<Button fx:id="btn2" ... padding="5" />

I don't know why is there this limitation for the "padding" property. I have seen on the FXML documentation that type coercion can be done implementing a valueOf() method for the given type :

public static Insets valueOf(String info) {
    // Data retrieval
}

But I don't know where to place it, because Insets class is locked (JDK). Because this is a static method, I thought that the method could be implemented elsewhere, but launching the application always gives me a coercion error :

Caused by: java.lang.IllegalArgumentException: Unable to coerce 0 5 10 5 to class javafx.geometry.Insets.

For the moment, the only solution I have found is to:

  • Define a new FXML component called GButton, that inherits Button
  • Define a Spacing class that inherits Insets and implement a valueOf method for this class
  • Add a "space" property for GButton (instance of ObjectProperty<Spacing>) which has the same behaviour as "padding", and define its getter and its setter.

Is there a simple way to define FXML "padding" into the Button markup, without creating a class inherited from Insets?
By the way don't forget to upvote if the question is useful :)


Solution

  • I don't know why is there this limitation for the "padding" property. I have seen on the FXML documentation that type coercion can be done implementing a valueOf() method for the given type

    This would require Insets to implement a static valueOf(String) method. This method does not exist in that type; therefore you cannot simply specify the value via an attribute.

    Introduction to FXML:

    Additional conversions can be implemented by defining a static valueOf() method on the target type.

    You could use the style property to specify the value via CSS though. This is often shorter than assigning an object to a property:

    <Button fx:id="btn1" style="-fx-padding: 0 5 10 5;" .../>
    

    For more on the supported properties/syntax, take a look at the CSS Reference Guide.