See thread at http://mail.openjdk.java.net/pipermail/openjfx-dev/2014-January/012272.html
For background, consider an implementation of StyleableProperty and CssMetaData as it is now.
public class MyControl extends Control {
public BooleanProperty fooProperty() { return (BooleanProperty)foo; }
private StyleableProperty<Boolean> foo = new SimpleStyleableBooleanProperty(fooMetaData);
private static final CssMetaData<MyControl,Boolean> fooMetaData = new CssMetaData<>("-my-foo", StyleConverter.getBooleanConverter()) {
@Override public boolean isSettable(MyControl node) { return !node.fooProperty().isBound(); }
@Override public StyleableProperty<Boolean> getStyleableProperty(MyControl node) { return node.foo; }
}
static final List<CssMetaData<? extends Styleable, ?>> cssMetaData;
static {
List<CssMetaData<? extends Styleable, ?>> temp = new ArrayList<>(Control.getClassCssMetaData());
temp.addAll(Arrays.asList(fooMetaData));
cssMetaData = Collections.unmodifiableList(temp);
}
}
From the high-level view, there are two pieces here. First is the StyleableProperty which is used by CSS to set the calculated value of a style on a property. The second piece is the CssMetaData which is used by CSS to (primarily) discover what css properties to look up for a node (e.g., -fx-fill), and to get the StyleableProperty for setting the value (e.g., get the StyleableProperty that corresponds to -fx-fill).
There are two abstract methods in CssMetaData that have to be implemented: boolean isSettable(S styleable) and StyleableProperty<V> getStyleableProperty(S styleable). The first method should return true if the property corresponding to the CssMetaData can be set by CSS. Typically, this means that the property is not null or bound. The second method simply returns the StyleableProperty that corresponds to the CssMetaData.
The reason that these methods take <? extends Styleable> as an argument is because the CssMetaData should be static. The getCssMetaData() method is called frequently so it is more efficient to return a static list. If the list were per-instance, then there wouldn't be a need to pass the Styleable as an argument.
So for every StyleableProperty, there has to be CssMetaData and that CssMetaData has to find its way into the list returned by getCssMetaData(). The code lends itself to copy-n-paste (and the errors inherent therein).
The objective is to simply reduce the amount of code that has to be written to support adding StyleableProperty to a node.
For background, consider an implementation of StyleableProperty and CssMetaData as it is now.
public class MyControl extends Control {
public BooleanProperty fooProperty() { return (BooleanProperty)foo; }
private StyleableProperty<Boolean> foo = new SimpleStyleableBooleanProperty(fooMetaData);
private static final CssMetaData<MyControl,Boolean> fooMetaData = new CssMetaData<>("-my-foo", StyleConverter.getBooleanConverter()) {
@Override public boolean isSettable(MyControl node) { return !node.fooProperty().isBound(); }
@Override public StyleableProperty<Boolean> getStyleableProperty(MyControl node) { return node.foo; }
}
static final List<CssMetaData<? extends Styleable, ?>> cssMetaData;
static {
List<CssMetaData<? extends Styleable, ?>> temp = new ArrayList<>(Control.getClassCssMetaData());
temp.addAll(Arrays.asList(fooMetaData));
cssMetaData = Collections.unmodifiableList(temp);
}
}
From the high-level view, there are two pieces here. First is the StyleableProperty which is used by CSS to set the calculated value of a style on a property. The second piece is the CssMetaData which is used by CSS to (primarily) discover what css properties to look up for a node (e.g., -fx-fill), and to get the StyleableProperty for setting the value (e.g., get the StyleableProperty that corresponds to -fx-fill).
There are two abstract methods in CssMetaData that have to be implemented: boolean isSettable(S styleable) and StyleableProperty<V> getStyleableProperty(S styleable). The first method should return true if the property corresponding to the CssMetaData can be set by CSS. Typically, this means that the property is not null or bound. The second method simply returns the StyleableProperty that corresponds to the CssMetaData.
The reason that these methods take <? extends Styleable> as an argument is because the CssMetaData should be static. The getCssMetaData() method is called frequently so it is more efficient to return a static list. If the list were per-instance, then there wouldn't be a need to pass the Styleable as an argument.
So for every StyleableProperty, there has to be CssMetaData and that CssMetaData has to find its way into the list returned by getCssMetaData(). The code lends itself to copy-n-paste (and the errors inherent therein).
The objective is to simply reduce the amount of code that has to be written to support adding StyleableProperty to a node.