如何在 JavaFx 中绑定 TextField 和 ProgressBar

How to bind TextField and ProgressBar in JavaFx

我正在尝试使用反应式绑定将 alcoholPercentageField 的值绑定到 alcoholBar 的进度 属性。 当酒精含量设置为 20% 时进度条将“充满”,当酒精含量为 0

时进度条为空

我的代码-

    public void start(Stage stage) throws Exception {
    stage.setTitle("Mead calculator");

    // Creating the fields and components
    TextField waterAmountField = new TextField();

    TextField alcoholPercentageField = new TextField();

    TextField sugarAmountField = new TextField();
    Label meadTotalAmount = new Label();
    Label assessmentLabel = new Label("");
    //assessmentLabel.textProperty().bind(alcoholPercentageField.textProperty());

    //Conditional Binding Error 

    assessmentLabel.textProperty().bind(Bindings.when((alcoholPercentageField.textProperty().lessThan(5))).then("Smart").otherwise("Bad"));

    ProgressBar alcoholBar = new ProgressBar();

    //Error is here
    alcoholBar.progressProperty().bind(alcoholPercentageField.textProperty() * 5);

其余代码:一些视觉效果

GridPane grid = new GridPane();
    grid.setAlignment(Pos.CENTER);
    grid.setHgap(10);
    grid.setVgap(10);
    grid.setPadding(new Insets(25, 25, 25, 25));
    var columnOneConstraints = new ColumnConstraints(150, 150, Double.MAX_VALUE);
    columnOneConstraints.setHalignment(HPos.RIGHT);
    var columnTwoConstrains = new ColumnConstraints(200,200, Double.MAX_VALUE);
    columnTwoConstrains.setHgrow(Priority.SOMETIMES);
    grid.getColumnConstraints().addAll(columnOneConstraints, columnTwoConstrains);
    alcoholBar.setMaxWidth(Double.MAX_VALUE);
    GridPane.setColumnSpan(alcoholBar, 2);
    GridPane.setHalignment(assessmentLabel, HPos.RIGHT);
    sugarAmountField.setDisable(true);

    grid.add(new Label("Water (l):"), 0, 0);
    grid.add(waterAmountField, 1, 0);
    
    grid.add(new Label("Vol-%:"), 0, 1);
    grid.add(alcoholPercentageField, 1, 1);

    grid.add(new Label("Sugar (kg):"),  0, 2);
    grid.add(sugarAmountField, 1, 2);

    grid.add(new Label("Lemons: "), 0, 3);
    grid.add(new Label("To taste"), 1, 3);

    grid.add(new Label("Mead total (kg):"), 0, 4);
    grid.add(meadTotalAmount, 1, 4);

    grid.add(alcoholBar, 0, 5);
    grid.add(assessmentLabel, 1, 6);
    // Okay, layout creation stops here
    
    
    // And of course set the scene and show the stage as always
    stage.setScene(new Scene(grid, 500, 400));
    stage.show();
}

}

使用 Bindings API.

请注意,进度应该在 0 到 1 之间,因此如果您在文本字段中输入百分比而不是比例,则需要除以 100:

alcoholBar.progressProperty().bind(Bindings.createDoubleBinding(
    () -> 0.05 * Double.parseDouble(alcoholPercentageField.getText()),
    alcoholPercentageField.textProperty()
));

您可能想要实现更复杂的逻辑,例如检查有效数字,或至少 non-empty 个文本字段。

您需要创建一些额外的 属性 和 Binding 对象。

首先,为您的 TextField 创建属性 alcoholPercentageField。然后,您将使用 StringConverter 绑定它们以将输入的文本转换为双精度值。

最后用bindBidirectional传播最后绑定progressBar除以20(酒精含量设置为20%时进度条会“满”)

代码会是这样-

    // Properties used for bindings
    DoubleProperty alcoholPercent = new SimpleDoubleProperty();

    //Setup the converters to get the input from the textfields
    StringConverter<? extends Number> converter = new DoubleStringConverter();
    
    Bindings.bindBidirectional(alcoholPercentageField.textProperty(), alcoholPercent, (StringConverter<Number>) converter);
    alcoholBar.progressProperty().bind(alcoholPercent.divide(20));

For Conditional Binding, check this

Code would be like this-

    assessmentLabel.textProperty().bind(Bindings.when(alcoholPercent.lessThan(5)).then("Smart").otherwise("Bad"));
    assessmentLabel.textFillProperty().bind(Bindings.when(alcoholPercent.lessThan(5)).then(Color.GREEN).otherwise(Color.RED));