CSS metadata boilerplate

John Hendrikx hjohn at xs4all.nl
Tue Jan 7 18:34:24 PST 2014


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