как сделать StylableDoubleProperty редактируемым в сцены - PullRequest
1 голос
/ 12 июня 2019

У меня есть набор пользовательских элементов управления, реализованных в виде стандартной пары классов, которые расширяют javafx.scene.control.Control и javafx.scene.control.SkinBase. По сути, они представляют собой набор составных элементов управления с меткой и одним или несколькими элементами управления «данные», такими как TextBox для значения и ChoiceBox для единицы измерения.

У меня есть несколько свойств, которые корректно взаимодействуют с SceneBuilder, однако два свойства, value и min-label-width, отображаются в SceneBuilder только для чтения. Как сделать эти свойства редактируемыми в SceneBuilder? Они работают правильно при программном манипулировании, когда элементы управления используются в контроллере FXML.

Я сделал скины min-label-width с помощью CssMetaData, но это не имело значения. Я искал исходный код 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();
                }

            };

Я ожидаю, что смогу редактировать запись Min Label Width в пользовательском разделе инспектора свойств Java, но это поле серого цвета и доступно только для чтения.

Ответы [ 2 ]

1 голос
/ 12 июня 2019

Вы на правильном пути.

Как и любой объект CSSMetaData, MIN_LABEL_WIDTH должен быть создан в этом приватном StyleableProperties классе (см., Например, TextField ),и затем добавляется в список STYLEABLES, который возвращается элементом getClassCssMetaData() элемента управления.

Также не забудьте добавить правильные типы: CssMetaData<CustomControl, Number>.

Это работает для меня:

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();
}

Скомпилируйте и соберите свой элемент управления и импортируйте банку в сцену.Builder.Это должно быть редактируемым:

Styleable property

Убедитесь, что вы используете правильную версию Scene Builder.Я строю на 11/12, поэтому я использую Scene Builder 11.0.0 .

0 голосов
/ 17 июня 2019

После поиска по разным поисковым терминам я нашел НАМНОГО более простой способ решения моей проблемы: 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);}

private static finalList> STYLEABLES;static {final List> styleables = new ArrayList <> (FACTORY.getCssMetaData ());styleables.add (StyleableProperties.ORIENTATION);

  STYLEABLES = Collections.unmodifiableList(styleables);

}

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