由于表示总数的文本字段不可编辑,因此这里不需要双向绑定,只需一个常规绑定即可在计算值更改时更新一个值(总数的值)。
您可以做类似的事情
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
。)从语义的角度来看也是有道理的:如果您知道总数,就没有确定价格和数量的唯一方法,这是唯一的。但是,如果您知道价格和数量,就可以确定总数。因此关系不是对称的。
这是一个完整的工作示例。例如,这可能可以大大改善。通过使用限制有效条目的TextFormatter
和使用本地化数字格式等的自定义StringConverter
实现方式。
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(),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();
}
}
本文链接:https://www.f2er.com/1798352.html