【问题标题】:how to make a StylableDoubleProperty editable in scenebuilder如何在场景构建器中使 StylableDoubleProperty 可编辑
【发布时间】:2019-06-12 15:02:51
【问题描述】:

我有一组自定义控件实现为扩展 javafx.scene.control.Control 和 javafx.scene.control.SkinBase 的标准类对。本质上,它们是一组带有标签和一个或多个“数据”控件的复合控件,例如用于值的 TextBox 和用于度量单位的 ChoiceBox。

我有几个属性可以与 SceneBuilder 正确交互,但是两个属性 value 和 min-label-width 在 SceneBuilder 中显示为只读。如何使这些属性在 SceneBuilder 中可编辑?当在 FXML 控制器中使用控件时,它们在以编程方式操作时可以正常工作。

我使用 CssMetaData 使 min-label-width 可换肤,但这并没有什么区别。我一直在查看 controlsFX 源代码以获取有关如何做事的模板,但还没有找到答案。

// --- min-label-width Defines the space for the label of the control so that
// controls can easily be lined up.

private DoubleProperty minLabelWidth;

public final void setMinLabelWidth(double val)
{
    minLabelWidthProperty().set(val);
}

public final Double getMinLabelWidth()
{
    return minLabelWidthProperty().get();
}

/**
 * lazy allocation of DoubleProperty minLabelWidth.
 *
 * @return the minLabelWidth
 */
public final DoubleProperty minLabelWidthProperty()
{
    if (minLabelWidth == null)
    {
        minLabelWidth = new StyleableDoubleProperty(100.0)
        {

            @Override
            public Object getBean()
            {
                return CustomControl.this;
            }

            @Override
            public String getName()
            {
                return "minLabelWidth"; //$NON-NLS-1$
            }

            @Override
            public CssMetaData<? extends Styleable, Number> getCssMetaData()
            {
                return StyleableProperties.MIN_LABEL_WIDTH;
            }
        };
    }
    return minLabelWidth;
}

 private static final CssMetaData<CustomControl, Number> MIN_LABEL_WIDTH =
            new CssMetaData<CustomControl, Number>("-min-label-width", SizeConverter.getInstance(), 100)
            {

                @Override
                public Number getInitialValue(CustomControl node)
                {
                    // A vertical Slider should remain vertical
                    return node.getMinLabelWidth();
                }

                @Override
                public StyleableProperty<Number> getStyleableProperty(CustomControl arg0)
                {
                    return (StyleableProperty<Number>) arg0.minLabelWidthProperty();
                }

                @Override
                public boolean isSettable(CustomControl arg0)
                {

                    return arg0.minLabelWidth == null || !arg0.minLabelWidth.isBound();
                }

            };

我希望能够在 Java 的属性检查器的自定义部分中编辑 Min Label Width 条目,但该字段是灰色的并且是只读的。

【问题讨论】:

    标签: javafx properties custom-controls scenebuilder gluon


    【解决方案1】:

    你在正确的轨道上。

    与任何CSSMetaData 对象一样,MIN_LABEL_WIDTH 必须在此私有StyleableProperties 类中创建(参见例如TextField),然后添加到由控件的@987654329 返回的STYLEABLES 列表中@。

    还要注意添加正确的类型:CssMetaData&lt;CustomControl, Number&gt;

    这对我有用:

    private static class StyleableProperties {
    
         private static final CssMetaData<CustomControl, Number> MIN_LABEL_WIDTH =
                new CssMetaData<>("-min-label-width", SizeConverter.getInstance(), 100.0) {
    
            @Override
            public Number getInitialValue(CustomControl node) {
                // A vertical Slider should remain vertical
                return node.getMinLabelWidth();
            }
    
            @Override
            public StyleableProperty<Number> getStyleableProperty(CustomControl control) {
                return (StyleableProperty<Number>) control.minLabelWidthProperty();
            }
    
            @Override
            public boolean isSettable(CustomControl control) {
    
                return control.minLabelWidth == null || !control.minLabelWidth.isBound();
            }
    
        };
    
        private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
        static {
            final List<CssMetaData<? extends Styleable, ?>> styleables = 
                    new ArrayList<>(Control.getClassCssMetaData());
            styleables.add(MIN_LABEL_WIDTH);
    
            STYLEABLES = Collections.unmodifiableList(styleables);
        }
    }
    
    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
        return StyleableProperties.STYLEABLES;
    }
    
    @Override
    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
        return getClassCssMetaData();
    }
    

    编译并构建您的控件,然后将 jar 导入到 Scene Builder。它应该是可编辑的:

    确保您使用正确版本的 Scene Builder。我在 11/12 构建,所以我使用 Scene Builder 11.0.0

    【讨论】:

    • 谢谢你,何塞。不幸的是,我很难看到您的代码中有什么不同,但我确信这是一些微妙而重要的事情:-) 幸运的是,我通过使用 StyleablePropertyFactory 在 Oracle 演示文稿中找到了答案,它在第一次尝试时就可以正常工作。跨度>
    • 当然这两种解决方案几乎相同,尽管我同意StyleablePropertyFactory 更易于使用。它是在 8u40 中添加到 JavaFX 中的,因此它没有用于内置控件的源代码中,我们通常将其模仿为有效引用。
    【解决方案2】:

    在使用不同的搜索词进行搜索后,我发现了一种更简单的方法来解决我的问题:StyleablePropertyFactory。

    以下是我在哪里找到信息的参考: https://static.rainfocus.com/oracle/oow16/sess/1462484351438001p6a1/ppt/Custom%20Controls.pdf 。幻灯片 #88 根据我的需要进行了复制和更新,效果很好。但是,该示例没有显示如何设置默认值。此链接正确调用 Number 属性中的默认值。

    https://docs.oracle.com/javase/8/javafx/api/javafx/css/StyleablePropertyFactory.html

    这是非常简化的属性集。

    private static final StyleablePropertyFactory<CustomControl> FACTORY = 
            new StyleablePropertyFactory<>(Control.getClassCssMetaData());
    
    private final StyleableProperty<Number> titleWidth =
            FACTORY.createStyleableNumberProperty(this,"titleWidth", "title-width", s->s.titleWidth, 100.0);
    private final StyleableProperty<String> title =
            FACTORY.createStyleableStringProperty(this,"title","title", s->s.title);
    
    @SuppressWarnings("unchecked")
    public final ObservableValue<Number> titleWidthProperty() {return (ObservableValue<Number>) titleWidth;}
    
    public final Double getTitleWidth() { return titleWidth.getValue().doubleValue();}
    public final void setTitleWidth(Double value) {titleWidth.setValue(value);}
    
    public final StringProperty titleProperty() { return (StringProperty) title;}
    
    public final String getTitle() {return title.getValue();}
    public final void setTitle(String newTitle) {title.setValue(newTitle);}
    

    私有静态最终列表> STYLEABLES; 静止的 { 最终列表> styleables = new ArrayList(FACTORY.getCssMetaData()); styleables.add(StyleableProperties.ORIENTATION);

      STYLEABLES = Collections.unmodifiableList(styleables);
    

    }

    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
        return STYLEABLES;
        }
    

    【讨论】:

      猜你喜欢
      • 2018-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-02
      • 2023-01-13
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多