How to set FXML "padding" property in one line
Asked Answered
U

2

5

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 :)

Unearthly answered 20/8, 2019 at 11:14 Comment(0)
G
9

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.

Guillotine answered 20/8, 2019 at 12:10 Comment(1)
Thanks for your feedback, fabian :) CSS styling is a solution but it has limitations too : * CSS styling is a little bit less performant than direct FXML styling, which is notable when there is a huge HMI * Is it possible to bind data with that syntax? I believe that CSS style is only applied once, when the GUI is loaded.Unearthly
V
0

I know the question is old, but hopefully I can provide some insightful information. I had the same problem; unfortunately FXML doesn't have full documentation, but piecing together the initialization model makes it intuitive in my opinion.

In any case, you had the right approach, just didn't quite complete it:

<padding>
    <Insets top="10" right="20" bottom="30" left="40"/>
</padding>

will create a padding equivalent to CSS's padding: 10 20 30 40, which of course, you can change (and even use FXML variables I would assume).

In general, though, any class that has javafx.beans properties in the proper convention (see this tutorial for an explanation), you can quite easily create custom components in FXML and assign member values like you can with the Insets above.

Hope this helps anyone!

Vaquero answered 6/3, 2021 at 4:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.