как применить двунаправленный метод при вычислении числа между целым и двойным значением текстового поля в следующем коде? - PullRequest
0 голосов
/ 05 августа 2020

Я новичок в привязке, особенно в двунаправленной привязке. У меня есть три текстовых поля: количество, цена и общая сумма. следующий код из Интернета, который преобразовал эти текстовые поля в форматы Integer и Double для их значений.

    StringConverter<Number> converter = new NumberStringConverter();
    StringConverter<Double> toDouble = new DoubleStringConverter();
    
    TextFormatter<Number> quantity = new TextFormatter<>(converter);
    TextFormatter<Double> price = new TextFormatter<>(toDouble);
    TextFormatter<Double> total = new TextFormatter<>(toDouble);

    Quantity.setTextFormatter(quantity);
    Price.setTextFormatter(price);
    Total.setTextFormatter(total);
    
    total.valueProperty().bindBidirectional(Bindings.createObjectBinding(() -> {
        
        // ?????????????????????????????????????????
        
    }, quantity.valueProperty(), price.valueProperty()));
    

Пожалуйста, помогите заполнить расчет или любой другой способ вызвать изменение всякий раз, когда я ввожу другое текстовое поле?

1 Ответ

2 голосов
/ 05 августа 2020

Поскольку текстовое поле, представляющее итог, не редактируется, вам не нужна здесь двунаправленная привязка, просто обычная привязка, которая обновляет одно значение (значение итога) при изменении вычисленного значения.

Вы может делать что-то вроде

total.valueProperty().bind(Bindings.createObjectBinding(
    () -> quantity.getValue() * price.getValue(),
    quantity.valueProperty(), price.valueProperty()));

Методы Bindings.createXXXBinding(...) создают наблюдаемые значения, значения которых вычисляются (здесь по существу по формуле quantity * price). Привязка выражает тот факт, что при изменении вычисленного значения значение total должно измениться. Двунаправленная привязка выражает идею о том, что при изменении одного из двух значений другое должно быть установлено в соответствии с ним. Это просто не сработает в этом сценарии, потому что вы не можете установить вычисленное значение.

С точки зрения программирования это работает, потому что метод bindBidirectional() ожидает WritableValue (соответствующего типа) ; методы Bindings.createXXXBinding() возвращают ObservableValue, которое не является WritableValue. (Напротив, метод bind() ожидает только ObservableValue.) Это имеет смысл также с точки зрения semanti c: если вы знаете общую сумму, не существует единственного способа определить цену и количество; однако, если вы знаете цену и количество, вы можете определить общую сумму. Так что отношения не симметричны c.

Вот полный рабочий пример. Вероятно, это можно существенно улучшить, например, используя TextFormatter s, которые ограничивают допустимую запись, и пользовательские реализации StringConverter, которые используют локализованные числовые форматы, и т. Д. c.

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
import javafx.util.converter.DoubleStringConverter;
import javafx.util.converter.IntegerStringConverter;


public class App extends Application {

    @Override
    public void start(Stage stage) {
        
        TextFormatter<Integer> quantity = new TextFormatter<>(new IntegerStringConverter(), 0);
        TextFormatter<Double> price = new TextFormatter<>(new DoubleStringConverter(), 0.0);
        TextFormatter<Double> total = new TextFormatter<>(new DoubleStringConverter(), 0.0);
        
        
        
        total.valueProperty().bind(Bindings.createObjectBinding(
                () -> quantity.getValue() * price.getValue(), 
                quantity.valueProperty(), price.valueProperty()));
        
        TextField quantityTF = new TextField("0");
        quantityTF.setTextFormatter(quantity);
        
        TextField priceTF = new TextField("0.0");
        priceTF.setTextFormatter(price);
        TextField totalTF = new TextField();
        totalTF.setEditable(false);
        totalTF.setTextFormatter(total);
        
        
        GridPane root = new GridPane();
        ColumnConstraints leftCol = new ColumnConstraints();
        leftCol.setHalignment(HPos.RIGHT);
        ColumnConstraints rightCol = new ColumnConstraints();
        rightCol.setHalignment(HPos.LEFT);
        root.getColumnConstraints().setAll(
                leftCol, rightCol
        );
        root.setAlignment(Pos.CENTER);
        root.setPadding(new Insets(5));
        root.setHgap(5);
        root.setVgap(5);
        root.addRow(0, new Label("Price:"), priceTF);
        root.addRow(1, new Label("Quantity:"), quantityTF);
        root.addRow(2, new Label("Total:"), totalTF);
        
        stage.setScene(new Scene(root, 800, 500));
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...