Bindings.createObjectBinding и нулевые зависимости

У меня есть свойство node, которое является ObjectProperty<VBox>, и я хочу иметь свойство nodeSize, которое зависит от свойства node.

Это будет выглядеть так:

public final class PropertyProblem {

    public PropertyProblem() {
        nodeSize.bind(initNodeSizeBinding(node));
    }

    private ObjectBinding<Dimension2D> initNodeSizeBinding(ObjectProperty<VBox> nodeProperty) {
        return Bindings.createObjectBinding(() -> {
            if (nodeProperty.get() == null) {
                return null;
            }

            VBox node = nodeProperty.get();
            ReadOnlyDoubleProperty widthProperty = node.widthProperty(),
                    heightProperty = node.heightProperty();
            return new Dimension2D(widthProperty.get(), heightProperty.get());
        }, nodeProperty);
    }

    // node property
    private final ObjectProperty<VBox> node = new SimpleObjectProperty<>(this, "node", null);

    public ObjectProperty<VBox> nodeProperty() {
        return node;
    }

    public void setNode(VBox val) {
        node.set(val);
    }

    public VBox getNode() {
        return node.get();
    }

    // nodeSize property
    private final ReadOnlyObjectWrapper<Dimension2D> nodeSize = new ReadOnlyObjectWrapper<>
            (this, "nodeSize");

    public ReadOnlyObjectProperty<Dimension2D> nodeSizeProperty() {
        return nodeSize;
    }

    public Dimension2D getNodeSize() {
        return nodeSize.get();
    }

}

Давайте сосредоточимся на методе initNodeSizeBinding(). Проблема в том, что я не могу предоставить зависимости (ширину и высоту узла) для привязки, потому что, очевидно, свойство node может быть null. Есть ли другой способ справиться с этим без создания привязки каждый раз, когда свойство node меняет свое значение?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
0
371
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вам нужен Bindings.when, который является эквивалентом динамического связывания третичного оператора (то есть условия ? trueExpr : falseExpr​):

return Bindings
    .when(nodeProperty.isNotNull())
    .then(Bindings.createObjectBinding(
        () -> new Dimension2D(nodeProperty.get().getWidth(),
                              nodeProperty.get().getHeight()),
        Bindings.selectDouble(nodeProperty, "width"),
        Bindings.selectDouble(nodeProperty, "height"))
    .otherwise((Dimension2D) null);

Разве не должно быть Bindings.selectDouble(nodeProperty.get(), "width") вместо Bindings.selectDouble(nodeProperty, "width") и то же самое с ростом?

StackOverflow 09.12.2020 22:54

@StackOverflow Нет, потому что вы хотите, чтобы выбранное свойство width всегда было из VBox, которое находится в ObservableValue<VBox> в любой момент, а не только из VBox, которое есть, когда вызывается метод (для создания привязки).

Slaw 09.12.2020 23:25

Другие вопросы по теме