JavaFX:如何从GridPane中的dynimically创建的TextFields的值中计算平均值?

时间:2017-06-15 18:32:03

标签: java javafx javafx-2 javafx-8

我在JavaFx中创建一个应用程序,我在其中创建两个具有相同行数的两个GridPane,两个GridPanes都有文本字段,下面有一个像这样的按钮:

enter image description here

用户可以在GridPane中编写任意数字动态创建的TextFields,如下所示:

enter image description here

我想要的是当用户按下提交按钮程序时应计算每行中存在的值的总和,然后将每行计算的总和除以整个GridPane的TextFields总和,并在第二个GridPane中显示结果TextFields根据GridPane行位置,例如GridPane第0行计算结果应该显示在GridPane B第0行中,如下所示:

enter image description here

我正在创建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;
}

GridPane 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;
}

从特定行和列的表返回组件的方法:

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");

    }

1 个答案:

答案 0 :(得分:1)

我认为你的方法是以正确的方式实现这一点,你可以尝试这个,当点击按钮时(,用它的动作监听器包装它)( NB 。未经测试 ):

// 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));

    }
}