我有一个Label
,需要显示ObservableList
中的元素数量。我有IntegerBinding
设置,但是我还需要根据列表中有多少个元素来调整Label
的措词。
对于下面的MCVE,如果列表中只有一个元素,则应显示“列表包含1个项目”。但是,如果列表为空或包含多个项目,则“ item”必须为复数形式:“列表包含3个项目。”
我试图同时使用三元运算符和BooleanBinding
来执行此操作,但是由于三元表达式似乎只被评估一次,所以两者都没有任何作用。单击“添加”按钮不会更改Label
的“项目”部分。
代码
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();
}
}
答案 0 :(得分:3)
这是使用自定义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()中创建新的String。
答案 1 :(得分:2)
这是较短的等效项:
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!")
)
);