JavaFX:如何根据 GridPane 中动态创建的文本字段的值计算平均值?
JavaFX: How to calulcate average from the values of dynimically created TextFields inside GridPane?
我在 JavaFx 中创建了一个应用程序,其中我动态地创建了两个具有相同行数的 GridPanes,两个 GridPanes 都有文本字段,下面有一个这样的按钮:
用户可以像这样在 GridPane A 动态创建的 TextFields 中写入任何数字:
我想要的是,当用户按下提交按钮时,程序应该计算每行中存在的值的总和,然后将每行计算的总和除以整个 GridPane 的 TextFields 总和,并根据 GridPane 的行位置在第二个 GridPane 的 TextFields 中显示结果例如GridPane A第0行的计算结果应该像这样显示在GridPane B的第0行:
我正在像这样创建 GridPane GridPane A:
public static GridPane tableA(int rows, Button button){
GridPane table = new GridPane();
rowValidationBindings = new BooleanBinding[rows];
for(int i=0; i<rows; i++){
TextField textField1 = new TextField();
textField1.setAlignment(Pos.CENTER);
TextField textField2 = new TextField();
textField2.setAlignment(Pos.CENTER);
TextField textField3 = new TextField();
textField3.setAlignment(Pos.CENTER);
rowValidationBindings[i] = Bindings.createBooleanBinding(
() -> {
if (textField1.getText().matches("\d+") &&
textField2.getText().matches("\d+") &&
textField1.getText().matches("\d+") {
return true ;
} else {
return false ;
}
}, textField1.textProperty(), textField2.textProperty(), textField3.textProperty()
);
table.add(textField1, 0, i+1);
table.add(textField2, 1, i+1);
table.add(textField3, 2, i+1);
}
button.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! Stream.of(rowValidationBindings).allMatch(BooleanBinding::get),
rowValidationBindings
));
return table;
}
网格窗格 B
public static GridPane tableB(int rows, Button button){
GridPane table = new GridPane();
rowValidationBindings = new BooleanBinding[rows];
for(int i=0; i<rows; i++){
TextField textField1 = new TextField();
textField1.setAlignment(Pos.CENTER);
rowValidationBindings[i] = Bindings.createBooleanBinding(
() -> {
if (textField1.getText().matches("\d+") {
return true ;
} else {
return false ;
}
}, textField1.textProperty()
);
table.add(textField1, 0, i+1);
}
button.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! Stream.of(rowValidationBindings).allMatch(BooleanBinding::get),
rowValidationBindings
));
return table;
}
从 table 到特定行和列的 return 组件的方法:
public static Node getComponent (int row, int column, GridPane table) {
for (Node component : table.getChildren()) { // loop through every node in the table
if(GridPane.getRowIndex(component) == row &&
GridPane.getColumnIndex(component) == column) {
return component;
}
}
return null;
}
按钮点击实现:
@FXML
private void calcul() {
GridPane table = (GridPane) anchorPane.getChildren().get(0);
for(int i=1 ; i<=comboxBox.getValue(); i++){
String text0 = ((TextField) getComponent (i, 0, table)).getText();
String text1 = ((TextField) getComponent (i, 1, table)).getText();
String text2 = ((TextField) getComponent (i, 2, table)).getText();
System.out.println(text0 + " " + text1 + " " + text2);
System.out.println("Next Row");
}
我认为你的方法是实现这一点的正确方法,你可以尝试这个,当按钮被点击时(即用它的动作侦听器包装它)(注意.未测试):
// pass the numberOfRows which is comboxBox.getValue()
// pass tableA and tableB.
// fetch the numbers (in a String format) from all TextFields at every row in tableA
// and caclulate the result after parsing the Strings from each as double values
// set the result in the corresponding TextField in tableB in every loop
private void calcul(GridePane tableA, GridPane tableB, int numberOfRows) {
double result = 0;
for(int i=0 ; i<numberOfRows; i++){
result = (Double.parseDouble(((TextField) getComponent (i, 0, tableA)).getText()) +
Double.parseDouble(((TextField) getComponent (i, 1, tableA)).getText()) +
Double.parseDouble(((TextField) getComponent (i, 2, tableA)).getText()))
/ (numberOfRows*3);
((TextField) getComponent (i, 0, tableB)).setText(String.valueOf(result));
}
}
更新
OP在下面的评论中提供了更多解释后,上面的代码需要进行一些调整:
// pass the numberOfRows which is comboxBox.getValue()
// pass tableA and tableB.
private void calcul(GridePane tableA, GridPane tableB, int numberOfRows) {
// first get the total and store it in a variable
double total =0;
for(Node node : tableA){
if(node instanceof TextField){
total += Double.parseDouble(((TextField)node).getText());
}
}
// fetch the numbers (in a String format) from all TextFields at every row in tableA
// and calculate the average after parsing the Strings from each as double values
// set the average in the corresponding TextField in tableB in every loop
double average = 0;
for(int i=0 ; i<numberOfRows; i++){
average = (Double.parseDouble(((TextField) getComponent (i, 0, tableA)).getText()) +
Double.parseDouble(((TextField) getComponent (i, 1, tableA)).getText()) +
Double.parseDouble(((TextField) getComponent (i, 2, tableA)).getText()))
/ (total);
((TextField) getComponent (i, 0, tableB)).setText(String.valueOf(average));
}
}
我在 JavaFx 中创建了一个应用程序,其中我动态地创建了两个具有相同行数的 GridPanes,两个 GridPanes 都有文本字段,下面有一个这样的按钮:
用户可以像这样在 GridPane A 动态创建的 TextFields 中写入任何数字:
我想要的是,当用户按下提交按钮时,程序应该计算每行中存在的值的总和,然后将每行计算的总和除以整个 GridPane 的 TextFields 总和,并根据 GridPane 的行位置在第二个 GridPane 的 TextFields 中显示结果例如GridPane A第0行的计算结果应该像这样显示在GridPane B的第0行:
我正在像这样创建 GridPane GridPane A:
public static GridPane tableA(int rows, Button button){
GridPane table = new GridPane();
rowValidationBindings = new BooleanBinding[rows];
for(int i=0; i<rows; i++){
TextField textField1 = new TextField();
textField1.setAlignment(Pos.CENTER);
TextField textField2 = new TextField();
textField2.setAlignment(Pos.CENTER);
TextField textField3 = new TextField();
textField3.setAlignment(Pos.CENTER);
rowValidationBindings[i] = Bindings.createBooleanBinding(
() -> {
if (textField1.getText().matches("\d+") &&
textField2.getText().matches("\d+") &&
textField1.getText().matches("\d+") {
return true ;
} else {
return false ;
}
}, textField1.textProperty(), textField2.textProperty(), textField3.textProperty()
);
table.add(textField1, 0, i+1);
table.add(textField2, 1, i+1);
table.add(textField3, 2, i+1);
}
button.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! Stream.of(rowValidationBindings).allMatch(BooleanBinding::get),
rowValidationBindings
));
return table;
}
网格窗格 B
public static GridPane tableB(int rows, Button button){
GridPane table = new GridPane();
rowValidationBindings = new BooleanBinding[rows];
for(int i=0; i<rows; i++){
TextField textField1 = new TextField();
textField1.setAlignment(Pos.CENTER);
rowValidationBindings[i] = Bindings.createBooleanBinding(
() -> {
if (textField1.getText().matches("\d+") {
return true ;
} else {
return false ;
}
}, textField1.textProperty()
);
table.add(textField1, 0, i+1);
}
button.disableProperty().bind(Bindings.createBooleanBinding(
() -> ! Stream.of(rowValidationBindings).allMatch(BooleanBinding::get),
rowValidationBindings
));
return table;
}
从 table 到特定行和列的 return 组件的方法:
public static Node getComponent (int row, int column, GridPane table) {
for (Node component : table.getChildren()) { // loop through every node in the table
if(GridPane.getRowIndex(component) == row &&
GridPane.getColumnIndex(component) == column) {
return component;
}
}
return null;
}
按钮点击实现:
@FXML
private void calcul() {
GridPane table = (GridPane) anchorPane.getChildren().get(0);
for(int i=1 ; i<=comboxBox.getValue(); i++){
String text0 = ((TextField) getComponent (i, 0, table)).getText();
String text1 = ((TextField) getComponent (i, 1, table)).getText();
String text2 = ((TextField) getComponent (i, 2, table)).getText();
System.out.println(text0 + " " + text1 + " " + text2);
System.out.println("Next Row");
}
我认为你的方法是实现这一点的正确方法,你可以尝试这个,当按钮被点击时(即用它的动作侦听器包装它)(注意.未测试):
// pass the numberOfRows which is comboxBox.getValue()
// pass tableA and tableB.
// fetch the numbers (in a String format) from all TextFields at every row in tableA
// and caclulate the result after parsing the Strings from each as double values
// set the result in the corresponding TextField in tableB in every loop
private void calcul(GridePane tableA, GridPane tableB, int numberOfRows) {
double result = 0;
for(int i=0 ; i<numberOfRows; i++){
result = (Double.parseDouble(((TextField) getComponent (i, 0, tableA)).getText()) +
Double.parseDouble(((TextField) getComponent (i, 1, tableA)).getText()) +
Double.parseDouble(((TextField) getComponent (i, 2, tableA)).getText()))
/ (numberOfRows*3);
((TextField) getComponent (i, 0, tableB)).setText(String.valueOf(result));
}
}
更新
OP在下面的评论中提供了更多解释后,上面的代码需要进行一些调整:
// pass the numberOfRows which is comboxBox.getValue()
// pass tableA and tableB.
private void calcul(GridePane tableA, GridPane tableB, int numberOfRows) {
// first get the total and store it in a variable
double total =0;
for(Node node : tableA){
if(node instanceof TextField){
total += Double.parseDouble(((TextField)node).getText());
}
}
// fetch the numbers (in a String format) from all TextFields at every row in tableA
// and calculate the average after parsing the Strings from each as double values
// set the average in the corresponding TextField in tableB in every loop
double average = 0;
for(int i=0 ; i<numberOfRows; i++){
average = (Double.parseDouble(((TextField) getComponent (i, 0, tableA)).getText()) +
Double.parseDouble(((TextField) getComponent (i, 1, tableA)).getText()) +
Double.parseDouble(((TextField) getComponent (i, 2, tableA)).getText()))
/ (total);
((TextField) getComponent (i, 0, tableB)).setText(String.valueOf(average));
}
}