JavaFX 绑定 UI 到嵌套的 class 的 属性
JavaFX Bind UI to a nested class's property
我有一个名为 Passage
的 class,其中包含一个名为 Action
的不可观察的 class。 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 开始为空(因此标签开始为空),然后将 Action 分配给非空的东西(即调用 setAction()),则标签不会更新以反映更改.
我需要让 Action 可见吗?参见:
上面的解决方案使用了我不熟悉的单子操作。所以我阅读了这个有用的博客 post:http://tomasmikula.github.io/blog/2014/03/26/monadic-operations-on-observablevalue.html
我已经尝试使用 EasyBind 进行此绑定。
我创建了一个新的 class 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
开始为空然后变为非空,则不会更新标签。
我建议在 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());
我有一个名为 Passage
的 class,其中包含一个名为 Action
的不可观察的 class。 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 开始为空(因此标签开始为空),然后将 Action 分配给非空的东西(即调用 setAction()),则标签不会更新以反映更改.
我需要让 Action 可见吗?参见:
上面的解决方案使用了我不熟悉的单子操作。所以我阅读了这个有用的博客 post:http://tomasmikula.github.io/blog/2014/03/26/monadic-operations-on-observablevalue.html
我已经尝试使用 EasyBind 进行此绑定。
我创建了一个新的 class 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
开始为空然后变为非空,则不会更新标签。
我建议在 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());