简体   繁体   English

JavaFX复杂字符串绑定

[英]JavaFX complex string binding

I'm new to JavaFX and was wondering if the Bindings API allowed an easier way to achieve the following. 我是JavaFX的新手,想知道Bindings API是否允许一种更简单的方法来实现以下目标。 Consider a model that contains a database that may be null (because the database loads asynchronously) and a view that displays a label status reflecting the state of the database. 考虑一个模型,该模型包含一个可能为null的数据库(因为该数据库是异步加载的)和一个视图,该视图显示反映数据库状态的标签status If it is null it should say something like "Loading..." and if it isn't it should display how many items are in the database. 如果为null,则应显示“正在加载...”之类的信息;否则,应显示数据库中有多少项。 It also would be great if the status could reflect the size of the database as it grows or shrinks. 如果状态可以反映数据库的大小(随着数据库的增长或缩小),那也将是一个很好的选择。

So far, I understand that I could bind an integer property (size of the database) to the text property of the label by using a converter. 到目前为止,我知道可以使用转换器将整数属性(数据库的大小)绑定到标签的text属性。 This is fine, but I want the label to display more than the number. 很好,但是我希望标签显示的数字多于数字。 A localized string like "Loaded {0} items" precisely. 一个精确的本地化字符串,例如“已加载{0}个项目”。 And let's not forget that the database may still be null. 并且不要忘了数据库可能仍然为空。

This is the solution I have in place 这是我已有的解决方案

@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);
    }
}

It works, but is there a way to do it with a chain of bindings, or at least part of it? 它有效,但是有没有办法用一连串的绑定或至少一部分绑定呢? I've seen how powerful (and lenghty) boolean bindings can be but I'm not sure something as flexible is possible with string bindings. 我已经看到了布尔绑定有多么强大(和冗长),但是我不确定字符串绑定是否可以实现某些灵活的功能。

You can use Bindings.when , which is essentially a dynamic if/then binding: * 您可以使用Bindings.when ,它实质上是一个动态的if / then绑定: *

status.textProperty().bind(
    Bindings.when(model.databaseProperty().isNull())
        .then(bundle.getString("status.loading"))
        .otherwise(
            Bindings.selectInteger(model.databaseProperty(), "size").asString(
                bundle.getString("status.ready")))
);

However, the above assumes bundle.getString("status.ready") returns a java.util.Formatter string, not a MessageFormat string. 但是,以上假设bundle.getString("status.ready")返回的是java.util.Formatter字符串,而不是MessageFormat字符串。 In other words, it would need to be "Loaded %,d items" rather than "Loaded {0,number,integer} items" . 换句话说,它将需要是"Loaded %,d items"而不是"Loaded {0,number,integer} items"

Bindings doesn't have built-in support for MessageFormat, but if you really want to stick with MessageFormat (which is a legitimate requirement, as there are things MessageFormat can do which Formatter cannot), you can create a custom binding with Bindings.createStringBinding : 绑定不具有对MessageFormat的内置支持,但是如果您真的想坚持使用MessageFormat(这是一个合法的要求,因为MessageFormat可以做某些格式化程序无法做到的事情),则可以使用Bindings.createStringBinding创建自定义绑定。

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")))
);

* Actually, it's more like the ternary ? *其实更像是三元? : operator. :操作员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM