JavaFX: How to calulcate average from the values o

2019-08-02 07:54发布

I'm creating an application in JavaFx in which I'm creating two GridPanes dynimically with same number of rows, both GridPanes have textfields and below there is a Button like this:

enter image description here

User can write any number in GridPane A's dynamically created TextFields like this:

enter image description here

What I want is when user will press Submit button program should calculate sum of values present in each row and then divide each row calculated sum with whole GridPane's TextFields sum and display the result in second GridPane's TextFields according GridPane A row position e.g GridPane A row 0 calculation result should be displayed in GridPane B row 0 like this:

enter image description here

I'm creating GridPane like this 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;
}

Method to return component from table at specific row and column:

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

Button Click implementation:

    @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条回答
Emotional °昔
2楼-- · 2019-08-02 08:17

I think your approach is on the right way to achieve that, you may try this, when the button is clicked (i.e wrap it with its action listener) (NB. Untested):

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

     }
}

UPDATE

After OP provided more explanation in the below comments, a few adjustments the above code needs:

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

    }
}
查看更多
登录 后发表回答