Предполагается, что разработчики должны реализовать свои собственные XXXProperties в JavaFX? - PullRequest
0 голосов
/ 19 октября 2018

Я читаю о свойствах javafx и не могу понять, почему неабстрактные классы, которые мы можем использовать для создания экземпляров свойств (например, SimpleStringProperty), имеют в именах Simple слово.Как я знаю, Simple в реализации означает basic реализацию чего-либо.

Предполагается ли, что разработчики должны реализовать свой собственный XXXProperty, который должен расширять XXXPropertyBase в JavaFX?

Давайте рассмотрим, например, SimpleStringProperty.

 java.lang.Object
    javafx.beans.binding.StringExpression
        javafx.beans.property.ReadOnlyStringProperty
            javafx.beans.property.StringProperty
                javafx.beans.property.StringPropertyBase
                    javafx.beans.property.SimpleStringProperty 

Должны ли мы разработать наш собственный OurStringProperty, который будет расширяться StringPropertyBase?

В то же время в javadoc сказано, что javafx.beans.property.StringProperty class provides a full implementation of a Property wrapping a String value.Так зачем нам это SimpleStringProperty?Как это объяснить?

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Это зависит .

В стандартных библиотеках JavaFX есть довольно распространенный шаблон создания локальных или анонимных классов, расширяющих один из «базовых» классов (ReadOnlyXXXPropertyBase или *).1006 *).По моему опыту, это обычно делается по одной из двух причин:

  1. Это свойство только для чтения, значение которого управляется извне свойства.
  2. Что-то должно происходить внутри, когдасвойство недействительно.

Чтобы увидеть пример первого случая, взгляните на исходный код ListPropertyBase.Этот класс свойств имеет два собственных свойства empty и size, унаследованных от ListExpression.Эти свойства, как и ожидалось, отражают пустое и размерное состояние содержимого ObservableList.Эти свойства реализованы в виде локальных классов, но их значения управляются самим ObservableList.Класс ListPropertyBase просто заставляет их запускать события изменения при необходимости.

Во втором случае локальный или анонимный класс переопределяет защищенный метод invalidated, предоставляемый большинством (всеми?) Из XXXPropertyBaseклассы.Этот метод вызывается, когда свойство недействительно.Это позволяет реагировать без накладных расходов слушателя.Вы можете увидеть это в действии, посмотрев исходный код ButtonBase.Например, свойство onAction:

public final ObjectProperty<EventHandler<ActionEvent>> onActionProperty() { return onAction; }
public final void setOnAction(EventHandler<ActionEvent> value) { onActionProperty().set(value); }
public final EventHandler<ActionEvent> getOnAction() { return onActionProperty().get(); }
private ObjectProperty<EventHandler<ActionEvent>> onAction = new ObjectPropertyBase<EventHandler<ActionEvent>>() {
    @Override protected void invalidated() {
        setEventHandler(ActionEvent.ACTION, get());
    }

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

    @Override
    public String getName() {
        return "onAction";
    }
};

Когда свойство недействительно, метод invalidated регистрирует / отменяет регистрацию EventHandler в Node.

со всемиТем не менее, если вам не нужно добавлять настраиваемую поведенческую ручку к использованию ReadOnlyXXXWrapper для свойств только для чтения и SimpleXXXProperty для свойств чтения и записи.


Simple?

Почему у конкретных реализаций есть Simple в названии?Почему бы просто не сделать XXXProperty конкретной реализацией?

Я не могу дать однозначного ответа, поскольку не участвовал в разработке, но могу предположить: разработчики JavaFX хотели предоставить несколько«точки расширения», которые предлагают различные степени «уже реализованы».Нужна полная настройка?Продлить XXXProperty.Нужна настройка?Продлить XXXPropertyBase.И так далее.

И классам SimpleXXXProperty нужны имена, которые не конфликтуют с именами классов XXXProperty.Simple подходит, потому что это то, что они есть - простые реализации.Они делают только то, что требуется интерфейсам.


Стоит упомянуть

На уровне API практически каждый класс JavaFX предоставляет свойства как ReadOnlyXXXProperty или XXXProperty.Никогда это не Property<SomeObject> или SimpleXXXProperty.В основном, когда дело доходит до свойств, рассмотрите возможность использования ReadOnlyXXXProperty и XXXProperty в качестве «программирования для интерфейса».Точно так же, как вы выставили бы List вместо ArrayList.

Я также рассмотрел бы эту цитату:

Этот класс обеспечивает полную реализацию Property упаковкизначение String.

Вводить в заблуждение.Если вы посмотрите на источник StringProperty, это, конечно, не"полная реализация".Может быть, он пытается сказать, что это класс уровня API?Может быть, он пытается сказать, что он реализует все необходимые интерфейсы?Честно говоря, понятия не имею ...

0 голосов
/ 20 октября 2018

Вот пример того, как добавить простое свойство Object-based к вашему классу, используя реализации, предоставляемые JavaFX (аналогичные классы существуют для типов String и примитивов):

private final ObjectProperty<Foo> foo = new SimpleObjectProperty<>(this,
        "foo", null);

public final Foo getFoo() {
    return fooProperty().get();
}

public final void setFoo(Foo foo) {
    fooProperty().set(foo);
}

public ObjectProperty<Foo> fooProperty() {
    return foo;
}

Вот примерреализация свойства только для чтения, основанная на некоторых базовых классах, предоставляемых JavaFX:

public class MyClass {

    private final ReadOnlyBarProperty bar = new ReadOnlyBarProperty();

    public final Bar getBar() {
        return barProperty().get();
    }

    private void setBar(Bar bar) {
        this.bar.set(bar);
    }

    public ReadOnlyObjectProperty<Bar> barProperty() {
        return bar;
    }

    [...]

    private class ReadOnlyBarProperty extends ReadOnlyObjectPropertyBase<Bar> {

        private Bar bar = null;

        @Override
        public final Bar get() {
            return bar;
        }

        private void set(Bar newValue) {
            if (!Objects.equals(bar, newValue)) {
                bar = newValue;
                fireValueChangedEvent();
            }
        }

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

        @Override
        public String getName() {
            return "bar";
        }
    }
}

Тогда есть несколько редких случаев, когда вы хотите предоставить собственную реализацию свойства.Например, я написал SimpleEventHandlerProperty в Drombler Commons .

Я надеюсь, что эти примеры немного прояснили ситуацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...