<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>I have a draft PR for this now.</p>
<p>I'd appreciate some feedback, before I flesh this out completely
(I'd need to add CSS documentation for example).</p>
<p><a class="moz-txt-link-freetext" href="https://github.com/openjdk/jfx/pull/1714">https://github.com/openjdk/jfx/pull/1714</a></p>
<p>--John<br>
</p>
<div class="moz-cite-prefix">On 11/02/2025 23:47, John Hendrikx
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:7a13841d-af52-4ebb-a30f-8d3866f82285@gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<p>Hi list,</p>
<p>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.</p>
<p>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:</p>
<p style="margin:0;">.text-field {</p>
<p style="margin:0;"> -fx-background-color: yellow;</p>
<p style="margin:0;"> -fx-hbox-hgrow: ALWAYS;</p>
<p style="margin:0;"> -fx-hbox-margin: 5px;<br>
</p>
<p style="margin:0;">}</p>
<p>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.<br>
</p>
<p>How does it work?</p>
<p>- Containers that wish to add additional styleable properties
to their direct descendants implement this interface:</p>
<div style="background-color:#ffffff;padding:0px 0px 0px 2px;">
<div
style="color:#000000;background-color:#ffffff;font-family:"Consolas";font-size:11pt;white-space:pre;"><p
style="margin:0;"><span style="color:#0000a0;font-weight:bold;">public</span><span
style="color:#000000;"> </span><span
style="color:#0000a0;font-weight:bold;">interface</span><span
style="color:#000000;"> ChildStyleProvider {</span></p><p
style="margin:0;"><span style="color:#000000;"> List<CssMetaData<Styleable, ?>> getChildCssMetaData(Node child);</span></p><p
style="margin:0;"><span style="color:#000000;">}</span></p></div>
</div>
<p>- The CssMetaData they provide for these properties looks like
this for example:<br>
<br>
</p>
<div style="background-color:#ffffff;padding:0px 0px 0px 2px;">
<div
style="color:#000000;background-color:#ffffff;font-family:"Consolas";font-size:11pt;white-space:pre;"><p
style="margin:0;"><span style="color:#000000;"> </span><span
style="color:#0000a0;font-weight:bold;">new</span><span
style="color:#000000;"> CssMetaData<>(</span><span
style="color:#2a00ff;">"-fx-hbox-hgrow"</span><span
style="color:#000000;">, StyleConverter.</span><span
style="color:#000000;font-style:italic;">getEnumConverter</span><span
style="color:#000000;">(Priority.</span><span
style="color:#0000a0;font-weight:bold;">class</span><span
style="color:#000000;">)) {</span></p><p style="margin:0;"><span
style="color:#000000;"> </span><span
style="color:#646464;">@Override</span></p><p style="margin:0;"><span
style="color:#000000;"> </span><span
style="color:#0000a0;font-weight:bold;">public</span><span
style="color:#000000;"> </span><span
style="color:#0000a0;font-weight:bold;">boolean</span><span
style="color:#000000;"> isSettable(Styleable styleable) {</span></p><p
style="margin:0;"><span style="color:#000000;"> </span><span
style="color:#7f0055;font-weight:bold;">return</span><span
style="color:#000000;"> </span><span
style="color:#0000a0;font-weight:bold;">true</span><span
style="color:#000000;">;</span></p><p style="margin:0;"><span
style="color:#000000;"> }</span></p><p
style="margin:0;">
</p><p style="margin:0;"><span style="color:#000000;"> </span><span
style="color:#646464;">@Override</span></p><p style="margin:0;"><span
style="color:#000000;"> </span><span
style="color:#0000a0;font-weight:bold;">public</span><span
style="color:#000000;"> StyleableProperty<Priority> getStyleableProperty(Styleable styleable) {</span></p><p
style="margin:0;"><span style="color:#000000;"> </span><span
style="color:#7f0055;font-weight:bold;">return</span><span
style="color:#000000;"> ChildStyleProvider.</span><span
style="color:#000000;font-style:italic;">createProp</span><span
style="color:#000000;">(</span><span
style="color:#0000a0;font-weight:bold;">this</span><span
style="color:#000000;">, </span><span style="color:#2a00ff;">"hbox-hgrow"</span><span
style="color:#000000;">, child);</span></p><p style="margin:0;"><span
style="color:#000000;"> }</span></p><p
style="margin:0;"><span style="color:#000000;"> }</span></p></div>
</div>
<p>- A special <span style="color:#000000;">StyleableProperty </span>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.<br>
<br>
- The CssStyleHelper will see if the parent of the Node being
styled implements <span style="color:#000000;">ChildStyleProvider,
and if so will also </span>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.<br>
</p>
<p>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.<br>
</p>
<p>If people think this proposal has some merit, I can flesh it
out further and make it into a PR.</p>
<p>--John<br>
</p>
<p><br>
</p>
<br>
<p><br>
</p>
</blockquote>
</body>
</html>