代码之家  ›  专栏  ›  技术社区  ›  Zephyr

带条件内容的绑定标签?

  •  4
  • Zephyr  · 技术社区  · 6 年前

    Label 需要显示 ObservableList . 我有 IntegerBinding 设置,但我也需要调整的措辞 标签 基于列表中有多少元素。

    对于下面的MCVE,如果列表中只有一个元素,它应该显示“列表包含1个项目”。但是如果列表为空或包含多个项目,“项目”需要是复数:“列表包含3个项目。”

    我试着用三元运算符和 BooleanBinding ,但两者都没有任何效果,因为三元表达式似乎只求值一次。单击“添加”按钮不会更改 标签 .


    代码

    import javafx.application.Application;
    import javafx.beans.binding.Bindings;
    import javafx.beans.binding.IntegerBinding;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.geometry.Insets;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    
    public class Main extends Application {
    
        ObservableList<String> items = FXCollections.observableArrayList();
    
        private IntegerBinding listSize = Bindings.size(items);
    
        public static void main(String[] args) {
            launch(args);
        }
    
        @Override
        public void start(Stage primaryStage) {
    
            // Simple Interface
            VBox root = new VBox(10);
            root.setAlignment(Pos.CENTER);
            root.setPadding(new Insets(10));
    
            Label label = new Label();
    
            // Bind the label to display a size-aware notification
            label.textProperty().bind(
                    Bindings.concat("The list contains ", listSize,
                            ((items.size() != 1) ? " items!" : " item!"))
            );
    
            // Button to add items
            Button button = new Button("Add");
            button.setOnAction(event -> items.add("new item"));
    
            root.getChildren().addAll(label, button);
    
            // Show the stage
            primaryStage.setScene(new Scene(root));
            primaryStage.setTitle("Sample");
            primaryStage.show();
        }
    }
    


    当列表的大小改变时,我是否需要包含一个侦听器?
    2 回复  |  直到 6 年前
        1
  •  3
  •   Jai    6 年前

    下面是一个使用自定义StringBinding()的快速解决方案

    // Bind the label to display a size-aware notification
    label.textProperty().bind(new StringBinding() {
        { bind(listSize); }
    
        @Override
        protected String computeValue() {
            return "The list contains " + listSize.get() + ((items.size() != 1) ? " items!" : " item!");
        }
    
    });
    

    在上面的代码中,您将侦听listSize的更改,然后在computeValue()中创建新字符串。

        2
  •  3
  •   Jai    6 年前

    这是较短的等效值:

    label.textProperty().bind(Bindings.createStringBinding(
                                  () -> "The list contains " + listSize.get() + ((itemSize.get() != 1) ? " items!" : " item!",
                                  listSize
                              ));
    

    或者另一种选择:

    label.textProperty.bind(Bindings
                               .when(listSize.isEqualTo(1))
                               .then("The list contains 1 item!")
                               .otherwise(
                                   Bindings.concat("The list contains " + listSize + " items!")
                               )
                           );