Styling HBox/VBox/GridPane child properties (hgrow, margin, columnIndex, etc)

John Hendrikx john.hendrikx at gmail.com
Tue Feb 11 22:47:52 UTC 2025


Hi list,

I've done a little proof of concept where I've made some minor
modifications to CssStyleHelper to allow the CSS engine to offer
styleable properties on children, but defined by the container class.

What this means is that we can make it appear that direct children of a
container like GridPane, HBox and VBox have properties like: `vgrow`,
`hgrow`, `column-index`, `margin`, `halignment`, `fill-width` etc.  The
exact names can be chosen by the container in question.  For example, I
could style a child of an HBox like this:

.text-field {

    -fx-background-color: yellow;

    -fx-hbox-hgrow: ALWAYS;

    -fx-hbox-margin: 5px;

}

This will make it possible to do far more visual styling directly in
CSS.  As usual, unrecognized properties are ignored, so if you put this
text field in a VBox, nothing will happen.

How does it work?

- Containers that wish to add additional styleable properties to their
direct descendants implement this interface:

publicinterfaceChildStyleProvider {

List<CssMetaData<Styleable, ?>> getChildCssMetaData(Node child);

}

- The CssMetaData they provide for these properties looks like this for
example:

newCssMetaData<>("-fx-hbox-hgrow",
StyleConverter.getEnumConverter(Priority.class)) {

@Override

publicbooleanisSettable(Styleable styleable) {

returntrue;

}

@Override

publicStyleableProperty<Priority> getStyleableProperty(Styleable
styleable) {

returnChildStyleProvider.createProp(this, "hbox-hgrow", child);

}

}

- A special StyleableProperty is created as the "receiver" of CSS
styling that will store the value in the Node#getProperties map (where
normally these values are already stored when using the static methods
like HBox.setHGrow(Node, Priority) type methods).  This property is
cached as part of the same getProperties map, so it is only created once.

- The CssStyleHelper will see if the parent of the Node being styled
implements ChildStyleProvider, and if so will also process these
additional CssMetaData properties when any are present; this seems to be
fairly safe to do, as changing a Node's parent will reset all its
styling already. Some more tests are needed here, if moving this forward.

That is basically the change in a nutshell.  Not only does setting a
property like `-fx-hbox-hgrow` on a child now act as if you called
`HBox.setHGrow`, changing the style of the child can also change these
settings and HBox will instantly respond to the change.  When the style
is completely removed, it will also null the hgrow value which is
translated as removing that key from the Node#getProperties map.

If people think this proposal has some merit, I can flesh it out further
and make it into a PR.

--John



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20250211/f45e4b8b/attachment.htm>


More information about the openjfx-dev mailing list