CSS metadata boilerplate

Tom Eugelink tbee at tbee.org
Tue Jan 7 22:05:16 PST 2014

Yes, I had similar considerations. I was thinking about providing exactly such extended Property classes in JFXtras to remove as much of the boilerplate.


On 2014-1-8 3:34, John Hendrikx wrote:
> Hi List,
> I'm in the process of adding CSS metadata to a new control, and I noticed there is a lot of boilerplate.
> In order to reduce this, I've created some custom classes StyleableProperty classes (SimpleStyleableXXXProperty), which reduces the boilerplate significantly without sacrificing much (if any) performance.  The only thing that I cannot easily provide in this fashion is the static getClassCssMetaData method.  From the documentation I understand it is there just for convience for subclass creators and is not used by the CSS engine at all -- atleast, everything seems to work.
> The shortened version for CSS aware properties basically looks like:
>   private final SimpleStyleableDoubleProperty cellAlignment = new SimpleStyleableDoubleProperty(this, "cellAlignment", "-fx-cell-alignment", 0.8);
>   private final SimpleStyleableDoubleProperty density= new SimpleStyleableDoubleProperty(this, "density", "-fx-density", 0.02);
>   private final SimpleStyleableBooleanProperty reflectionEnabled= new SimpleStyleableBooleanProperty(this, "reflectionEnabled", "-fx-reflection-enabled", true);
>   private final SimpleStyleableBooleanProperty clipReflections= new SimpleStyleableBooleanProperty(this, "clipReflections", "-fx-clip-reflections", true);
> With one small bit of supporting code in the relevant class (Skin or Control), which is basically a non-static implementation of the standard CSS List example code:
>   private static List<CssMetaData<? extends Styleable, ?>> cssMetaData;
>   @Override
>   public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {  // Unsynchronized. WC: list gets initialized multiple times.
>     if(cssMetaData == null) {
>       List<CssMetaData<? extends Styleable, ?>> metaData = new ArrayList<>(super.getCssMetaData());
>       Collections.addAll(metaData,
>           cellAlignment.getCssMetaData(),
>           density.getCssMetaData(),
>           reflectionEnabled.getCssMetaData(),
>           clipReflections.getCssMetaData()
>       );
>       cssMetaData = Collections.unmodifiableList(metaData);
>     }
>     return cssMetaData;
>   }
> Note that the List is static and lazy-final.  The same goes for the getCssMetaData method in the SimpleStyleableXXXProperty classes.  There is a slight performance decrease in those classes as getCssMetaData is looked up from a static Map (indexed by Class + css property name) and lazily created as needed -- a Map lookup however should be quite fast enough.
> I'm sure the design had good reason to do things as they are, and I'm wondering if reducing the boilerplate has left me missing something important.
> I welcome any insights!
> --John

More information about the openjfx-dev mailing list