<div dir="ltr"><div>Hi,</div><div><br></div>Reflection is probably already being used in JavaFX and I think it's probably fine, but there's the case of graalvm native compiled JavaFX apps.<div><br></div><div>-- Thiago.</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Em ter., 5 de dez. de 2023 às 08:42, John Hendrikx <<a href="mailto:john.hendrikx@gmail.com">john.hendrikx@gmail.com</a>> escreveu:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">It looks good, and IMHO would be a major clean up, and would simplify <br>
creating stylable properties for users tremendously.<br>
<br>
I see you added a public API in CssMetaData, but I think you can just <br>
leave that private in CssMetaDataCache.  Users won't need it, as they <br>
should no longer be overriding getCssMetaData.  Old implementations are <br>
backwards compatible, so they won't need it either.<br>
<br>
Any new Nodes/Controls need not (or should not) provide the static <br>
getClassCssMetaData or override getCssMetaData.<br>
<br>
+1<br>
<br>
--John<br>
<br>
On 04/12/2023 07:02, Michael Strauß wrote:<br>
> Following up the discussion around the CssMetaData API, I'd like to<br>
> chime in with yet another idea. To recap, here's Nir's summary of the<br>
> current API [0]:<br>
><br>
> "Let's look at what implementation is required from a user who wants<br>
> to write their own styleable control:<br>
> 1. Create styleable properties.<br>
> 2. Create a list of these properties to be passed on.<br>
> 3. Create a public static method that returns the concatenation of<br>
> this list with the one of its parent. (This method happens to be<br>
> poorly documented, as mstr said.)<br>
> 4. Create a public non-static method that calls the static method in a<br>
> forced-override pattern because otherwise you will be calling the<br>
> wrong static method. (This method's docs seem to be just wrong because<br>
> you don't always want to delegate to Node's list.)"<br>
><br>
><br>
> I think this could reasonably be replaced with the following<br>
> implementation requirements:<br>
> 1. Create styleable properties.<br>
> 2. That's it.<br>
><br>
> Let's look at what we're actually trying to do: create a list of<br>
> CSS-styleable property metadata of a class. But we can easily do that<br>
> without all of the boilerplate code.<br>
><br>
> When ´Node.getCssMetaData()` is invoked, all public methods of the<br>
> class are reflectively enumerated, and metadata is retrieved from<br>
> `Property` and `StyleableProperty` getters. This is a price that's<br>
> only paid once for any particular class (i.e. not for every instance).<br>
> The resulting metadata list is cached and reused for all instances of<br>
> that particular class.<br>
><br>
> As a further optimization, metadata lists are also cached and<br>
> deduplicated for Control/Skin combinations (currently every Control<br>
> instance has its own copy of the metadata list).<br>
><br>
> Another benefit of this approach is that the CssMetaData can now be<br>
> co-located with the property implementation, and not be kept around in<br>
> other parts of the source code file. Here's how that looks like when a<br>
> new "myValue" property is added to MyClass:<br>
><br>
>      StyleableDoubleProperty myValue =<br>
>              new SimpleStyleableDoubleProperty(this, "myValue") {<br>
><br>
>          static final CssMetaData<MyClass, Number> METADATA =<br>
>              new CssMetaData<MyClass, Number>(<br>
>                  "-fx-my-value",<br>
>                  SizeConverter.getInstance(),<br>
>                  USE_COMPUTED_SIZE) {<br>
>              @Override<br>
>              public boolean isSettable(MyClass node) {<br>
>                  return !node.myValue.isBound();<br>
>              }<br>
><br>
>              @Override<br>
>              public StyleableProperty getStyleableProperty(<br>
>                      MyClass node) {<br>
>                  return node.myValue;<br>
>              }<br>
>          };<br>
><br>
>          @Override<br>
>          public CssMetaData getCssMetaData() {<br>
>              return METADATA;<br>
>          }<br>
>      };<br>
><br>
>      public final DoubleProperty myValueProperty() {<br>
>          return myValue;<br>
>      }<br>
><br>
> It is not required to override the `getCssMetaData()` method, nor is<br>
> it required to redeclare a new static `getClassCssMetaData()` method.<br>
> It is also not required to manually keep the list of styleable<br>
> properties in sync with the list of CSS metadata.<br>
><br>
> I've prototyped this concept for the `Node`, `Region` and `Control` classes [1].<br>
><br>
> [0] <a href="https://mail.openjdk.org/pipermail/openjfx-dev/2023-December/044046.html" rel="noreferrer" target="_blank">https://mail.openjdk.org/pipermail/openjfx-dev/2023-December/044046.html</a><br>
> [1] <a href="https://github.com/openjdk/jfx/pull/1299" rel="noreferrer" target="_blank">https://github.com/openjdk/jfx/pull/1299</a><br>
</blockquote></div>