JavaFX复杂字符串绑定
我是JavaFX新手,想知道BindingsAPI是否允许以更简单的方式实现以下内容。考虑一个模型,该模型包含一个可能是空的数据库(因为数据库异步加载)和一个显示标签“代码>状态< /代码>的视图,反映数据库的状态。如果为空,则应显示“加载…”之类的内容;如果不是空,则应显示数据库中有多少项。如果状态能够反映数据库在增长或收缩时的大小,那就太好了 到目前为止,我了解可以使用转换器将整数属性(数据库大小)绑定到标签的文本属性。这很好,但我希望标签显示的内容多于数字。类似“Loaded{0}items”的本地化字符串。我们不要忘记数据库可能仍然是空的 这就是我的解决方案JavaFX复杂字符串绑定,java,javafx-8,javafx-bindings,Java,Javafx 8,Javafx Bindings,我是JavaFX新手,想知道BindingsAPI是否允许以更简单的方式实现以下内容。考虑一个模型,该模型包含一个可能是空的数据库(因为数据库异步加载)和一个显示标签“代码>状态< /代码>的视图,反映数据库的状态。如果为空,则应显示“加载…”之类的内容;如果不是空,则应显示数据库中有多少项。如果状态能够反映数据库在增长或收缩时的大小,那就太好了 到目前为止,我了解可以使用转换器将整数属性(数据库大小)绑定到标签的文本属性。这很好,但我希望标签显示的内容多于数字。类似“Loaded{0}item
@Override
public void initialize(URL url, ResourceBundle bundle) {
// Initialize label with default value
status();
model.databaseProperty().addListener((obs, old, neu) -> {
// Update label when database is no longer null
status();
// Update label when size of database changes
neu.sizeProperty().addListener(x -> status());
});
}
public void status() {
if (model.database() == null) {
status.setText(bundle.getString("status.loading"));
} else {
String text = bundle.getString("status.ready");
int size = model.database().size();
text = new MessageFormat(text).format(size);
status.setText(text);
}
}
这是可行的,但是有没有一种方法可以通过绑定链或者至少部分绑定来实现呢?我已经看到了布尔绑定的强大性(以及长度),但我不确定字符串绑定是否可以实现如此灵活的功能。您可以使用它,它本质上是一种动态的if/then绑定:*
但是,上面假设bundle.getString(“status.ready”)
返回java.util.Formatter字符串,而不是MessageFormat字符串。换句话说,它需要“加载%,d项”
,而不是“加载{0,number,integer}项”
绑定没有内置的对MessageFormat的支持,但是如果您真的想坚持使用MessageFormat(这是一个合法的要求,因为MessageFormat可以做一些格式化程序不能做的事情),您可以使用以下内容创建自定义绑定:
*实际上,它更像是三元
?
…:
运算符。回答得好,谢谢。据我所知,select
只匹配getSize()
方法,而不是size()
方法,对吗?有什么方法可以改变这种行为吗?如果数据库类添加了一个public IntegerProperty sizeProperty()
方法,那就足够了。如果无法向数据库类添加方法,则可以将Bindings.selectInteger替换为Bindings.createIntegerBinding
,类似于createStringBinding的工作方式,但如果未将表示大小的一些可观察值传递给createIntegerBinding,当大小更改时,自定义绑定将不知道如何更新自身。经过进一步考虑,我意识到应该是public ReadOnlyIntegerProperty sizeProperty()
。另外还有一种表示size属性的可能性,尽管这需要更多的努力:您可以为数据库类创建一个自定义Beaninfo,如中所述,告诉bean属性发现过程哪些方法对应于类的每个属性。这可能是某些属性所必需的。我现在被一个事实难住了,select
根本无法匹配sorted()
方法的observeList
。具体来说,select(object,“list”,“sorted”)
将引发异常,即使object
有一个listProperty()
和getList()
方法。只需澄清一下,仍然可以进行((observeblist)绑定。select(object,“list”).get().sorted()
但这有点冗长
status.textProperty().bind(
Bindings.when(model.databaseProperty().isNull())
.then(bundle.getString("status.loading"))
.otherwise(
Bindings.selectInteger(model.databaseProperty(), "size").asString(
bundle.getString("status.ready")))
);
MessageFormat statusFormat = new MessageFormat(bundle.getString("status.ready"));
status.textProperty().bind(
Bindings.when(model.databaseProperty().isNull())
.then(bundle.getString("status.loading"))
.otherwise(
Bindings.createStringBinding(
() -> statusFormat.format(new Object[] { model.getDatabase().getSize() }),
model.databaseProperty(),
Bindings.selectInteger(model.databaseProperty(), "size")))
);