我有一个名为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()),则标签不会更新以反映更改。 / p>
我是否需要观察动作?请参阅:Binding to javafx properties of a object that can be null
上述解决方案使用了我不熟悉的monadic操作。所以我读了这篇有用的博文: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,则标签不会更新。
答案 0 :(得分:1)
我建议在Passage中拥有一个属性,该属性将与action的属性绑定。 设置新操作后,绑定它的属性并仅使用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());