javafx 扩展矩形添加新的可样式化属性

示例

JavaFX 8

以下示例演示如何将可以从css样式化的自定义属性添加到custom Node。

这里将2 DoublePropertys添加到Rectangle类中,以允许从CSS设置widthand height。

以下CSS可用于设计自定义节点的样式:

 StyleableRectangle {
    -fx-fill: brown;
    -fx-width: 20;
    -fx-height: 25;
    -fx-cursor: hand;
}

自定义节点

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javafx.beans.property.DoubleProperty;
import javafx.css.CssMetaData;
import javafx.css.SimpleStyleableDoubleProperty;
import javafx.css.StyleConverter;
import javafx.css.Styleable;
import javafx.css.StyleableDoubleProperty;
import javafx.css.StyleableProperty;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;

public class StyleableRectangle extends Rectangle {
    
    // 新属性的声明
    private final StyleableDoubleProperty styleableWidth = new SimpleStyleableDoubleProperty(WIDTH_META_DATA, this, "styleableWidth");
    private final StyleableDoubleProperty styleableHeight = new SimpleStyleableDoubleProperty(HEIGHT_META_DATA, this, "styleableHeight");

    public StyleableRectangle() {
        bind();
    }

    public StyleableRectangle(double width, double height) {
        super(width, height);
        initStyleableSize();
        bind();
    }

    public StyleableRectangle(double width, double height, Paint fill) {
        super(width, height, fill);
        initStyleableSize();
        bind();
    }

    public StyleableRectangle(double x, double y, double width, double height) {
        super(x, y, width, height);
        initStyleableSize();
        bind();
    }
    
    private void initStyleableSize() {
        styleableWidth.set(getWidth());
        styleableHeight.set(getHeight());
    }
    
    private final static List<CssMetaData<? extends Styleable, ?>> CLASS_CSS_META_DATA;
    
    // 用于width属性的CSS元数据
    // 将属性名称指定为-fx-width和
    // 使用数字转换器
    private final static CssMetaData<StyleableRectangle, Number> WIDTH_META_DATA = new CssMetaData<StyleableRectangle, Number>("-fx-width", StyleConverter.getSizeConverter()) {

        @Override
        public boolean isSettable(StyleableRectangle styleable) {
            // 如果属性未绑定,则可以设置属性
            return !styleable.styleableWidth.isBound();
        }

        @Override
        public StyleableProperty<Number> getStyleableProperty(StyleableRectangle styleable) {
            // 从可样式化中提取属性
            return styleable.styleableWidth;
        }
    };
    
    // height属性的CSS元数据
    // 将属性名称指定为-fx-height,
    // 使用数字转换器
    private final static CssMetaData<StyleableRectangle, Number> HEIGHT_META_DATA = new CssMetaData<StyleableRectangle, Number>("-fx-height", StyleConverter.getSizeConverter()) {

        @Override
        public boolean isSettable(StyleableRectangle styleable) {
            return !styleable.styleableHeight.isBound();
        }

        @Override
        public StyleableProperty<Number> getStyleableProperty(StyleableRectangle styleable) {
            return styleable.styleableHeight;
        }
    };
    
    static {
        // 将Rectangle中已经可用的属性与新属性相结合
        List<CssMetaData<? extends Styleable, ?>> parent = Rectangle.getClassCssMetaData();
        List<CssMetaData<? extends Styleable, ?>> additional = Arrays.asList(HEIGHT_META_DATA, WIDTH_META_DATA);

        // 创建具有适当容量的arraylist
        List<CssMetaData<? extends Styleable, ?>> own = new ArrayList(parent.size()+ additional.size());

        // 用新旧元数据填充列表
        own.addAll(parent);
        own.addAll(additional);
        
        // 确保元数据列表不可修改
        CLASS_CSS_META_DATA = Collections.unmodifiableList(own); 
    }
    
    // 使元数据可用于扩展类
    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
        return CLASS_CSS_META_DATA;
    }
    
    // 返回Node的可样式化属性的CSS元数据列表
    @Override
    public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() {
        return CLASS_CSS_META_DATA;
    }
    
    private void bind() {
        this.widthProperty().bind(this.styleableWidth);
        this.heightProperty().bind(this.styleableHeight);
    }


    // -------------------------------------------------- -----------------------
    // -----------------------属性方法------------------------- -------
    // -------------------------------------------------- -----------------------
    
    public final double getStyleableHeight() {
        return this.styleableHeight.get();
    }

    public final void setStyleableHeight(double value) {
        this.styleableHeight.set(value);
    }

    public final DoubleProperty styleableHeightProperty() {
        return this.styleableHeight;
    }

    public final double getStyleableWidth() {
        return this.styleableWidth.get();
    }

    public final void setStyleableWidth(double value) {
        this.styleableWidth.set(value);
    }

    public final DoubleProperty styleableWidthProperty() {
        return this.styleableWidth;
    }

}