The reason things are as they are is because most properties in the core 
classes are lazily created and I didn't want cause the property to be created 
just to see if it was bound. But that is a particular concern for the core 
classes and not so much for controls. 

I'm not sure if you are aware of the javafx.css.SimpleStyleableXXXProperty 
classes. I'd be interested to see how your custom classes dovetail into these 
as I'd be more than willing to consider taking  your additions and calling them 
my own… uh, um, I mean, rolling them into the source code. 

Have you looked at the initialization-on-demand holder pattern for creating the 
List?
 
On Jan 7, 2014, at 9:34 PM, John Hendrikx <hj...@xs4all.nl> 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

Reply via email to