1

我有一个名为的类Passage,其中包含一个名为Action. 并Action包含一个SimpleStringProperty.

class Passage {

    Action action = null;

    Action getAction() { return action; }

    void setAction(Action action) { this.action = action; }

    boolean hasAction() { return action != null; }
}

class Action {

    StringProperty myStringProperty = new SimpleStringProperty();

    StringProperty getStringProperty() { return myStringProperty; }

    // and other methods, many of which modify myStringProperty
}

我想将该字符串属性绑定到 UI 标签。看起来这应该是一件简单的事情:

label.textProperty.bind(passage.getAction().getStringProperty());

但是,Action有时可能为空。我尝试了以下方法:

label.textProperty.bind(passage.hasAction() ? passage.getAction().getStringProperty() : new SimpleStringProperty("") );

然后,如果 Action 以 null 开始(因此标签以空白开始),然后将 Action 分配给非 null 的东西(即调用 setAction()),则标签不会更新以反映更改。

我需要让 Action 可观察吗?请参阅:绑定到可以为 null 的对象的 javafx 属性

上面的解决方案使用了我不熟悉的一元操作。所以我读了这篇有用的博客文章:http ://tomasmikula.github.io/blog/2014/03/26/monadic-operations-on-observablevalue.html

我尝试使用 EasyBind 进行此绑定。

我创建了一个ObservableAction包装 的新类Action,使其成为可观察的值(尽管我不确定我是否正确执行了此步骤):

import javafx.beans.binding.ObjectBinding;

public class ObservableAction extends ObjectBinding <Action>
{
    private final Action value;

    public ObservableAction(Action action) {
        this.value = action;
    }

    @Override
    public Action computeValue()
    {
        return value;
    }
}

然后我的 ViewController 中有以下代码(同样,不确定我是否正确地完成了此操作):

MonadicObservableValue<Action> monadicAction = EasyBind.monadic(new ObservableAction(passage.getAction()));

actionLabel.textProperty().bind(monadicAction.flatMap(action -> action.getTextProperty()).orElse(""));

结果和我之前经历的一样:当它Action不为空时它工作得很好。但是,如果Action开始为 null 然后变为非 null,则不会更新标签。

4

1 回答 1

1

我建议在 Passage 中有一个属性,它将与动作的属性绑定。一旦你设置了一个新动作,你就绑定它的属性并且只使用 Passage 的那个。

class Passage {
    private Action action;

    private StringProperty actionMyStringProperty = new SimpleStringProperty();

    void setAction(Action action) {
        this.action = action;

        // Unbind the previous binding if any (it is safe when nothing to unbind).
        actionMyStringProperty.unbind();

        if (action != null){
            actionMyStringProperty.bind(action.getStringProperty());
        }
    }

    public StringProperty actionMyStringProperty() {
        return actionMyStringProperty;
    }
}

class Action {
    private StringProperty myStringProperty = new SimpleStringProperty();

    StringProperty getStringProperty() {
        return myStringProperty;
    }
}

在客户端:

label.textProperty.bind(passage.actionMyStringProperty());
于 2017-07-12T22:11:07.520 回答