概述
css屬性是啥?就像background-color、font-size這樣的,決定了組件樣式特點和渲染效果的東西,就是css屬性。
爲啥要自己自定義css屬性呢?
其實是在封裝javaFX組件的時候使用了canvas,canvas的特性,像是顏色,背景畫筆粗細什麼的,都用得java控制,這樣一來,如果其他地方更換了css,他們整體的配色和風格就會大變樣,canvas繪製的效果就和其他位置“畫風”不一致,非常彆扭,如果canvas也能有這些屬性,我們就可以根據css屬性來決定該畫成什麼樣子的,這就比較好了。
那麼該怎麼做呢
javafx組件的CSS屬性是由CssMetaData,StyleableProperty這兩個進行控制的,爲了方便我們使用,javaFX提供了一個Factor接口,創建自定義的屬性就要從這個factor入手了。其實通過factory入手非常簡單,就像這樣,很容易就能夠增加一個新的css屬性了:
javafx組件的CSS屬性是由CssMetaData
,StyleableProperty
這兩個進行控制的,爲了方便我們使用,javaFX提供了一個Factor接口,創建自定義的屬性就要從這個factor入手了。其實通過factory入手非常簡單,就像這樣,很容易就能夠增加一個新的css屬性了:
public class StyleableCanvas extends Canvas {
private static final StyleablePropertyFactory<StyleableCanvas> factory =
new StyleablePropertyFactory<>(Canvas.getClassCssMetaData());
private StyleableProperty<Color> background =
factory.createStyleableColorProperty(this,
"background", "-c-background-color");
protected static final CssMetaData<StyleableCanvas, Color> BACKGROUND_META_DATA =
factory.createColorCssMetaData("-c-background-color",
c -> c.background, Color.BLACK);
@Override
public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
return factory.getCssMetaData();
}
public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
return factory.getCssMetaData();
}
}
那麼現在解釋一下他的含義:
StyleablePropertyFactory是一個用來創建屬性,以及屬性的MetaData的工廠,屬性用來存放組件具體的屬性值,metaData可以看成是屬性名稱和控件屬性值的對應關係的描述,getCssMetaData和getClassMetaData一般我們不會手動調用,一般來說是javafx解析和渲染時候會通過這個讀取css樣式,我們需要把自己的新屬性加入這兩個方法的返回值中,這樣新的屬性就能夠被javafx正確解析到了。
至於這裏屬性的metadata是protected的原因,是因爲我需要在同一個package訪問他來讀取這個自定義的屬性,以此進行canvas的繪製,其實如果不需要在外面獲取新屬性的話,他完全可以是private的。
css的解析是需要一點時間的,如果想要打印到控制檯上面,可以在監聽事件中打印,因爲setStyle之後屬性並不會馬上生效。
效果測試
以上設定了-c-background屬性,他默認是黑的,我將他設爲#FFF,然後在鼠標事件中進行讀取:
canvas.setOnMouseMoved(e -> {
System.out.println(StyleableCanvas.BACKGROUND_META_DATA
.getStyleableProperty(canvas).getValue());
});
可見,新的屬性以及生效。
PS:本文原創,最早是放在知乎的,CSDN一段時間沒有來了。