JavaFX:如何从 GridPane 中动态创建的文本字段的值计算平均值?

Posted

技术标签:

【中文标题】JavaFX:如何从 GridPane 中动态创建的文本字段的值计算平均值?【英文标题】:JavaFX: How to calulcate average from the values of dynimically created TextFields inside GridPane? 【发布时间】:2017-06-15 18:32:02 【问题描述】:

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

用户可以像这样在 GridPane A 的动态创建的 TextField 中写入任意数字:

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

我正在创建这样的 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;

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

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

    

【问题讨论】:

我们很清楚您需要什么,但我认为您没有告诉我们问题所在...... 我很确定几天前已经回答了这个问题。 @SedrickJefferson 如果它已经回答了,你可以在这里标记已经回答的问题吗? 不一样但非常相似:***.com/questions/44413649/… 【参考方案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在下面的cmets中提供了更多的解释之后,上面的代码需要做一些调整:

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

    

【讨论】:

感谢@Yahya 的回答,但我认为我没有清楚地解释我的问题。我将再次尝试解释,第一个:如果您看到屏幕截图 2,我想要逐行计算总和,在第 1 行中有三个值:1,0,0 所以第 1 行的总和将为 1+0+0 =1,第 2 行为 1+4+0=5,第 3 行为 2+0+1=3,第 4 行为 1+1+2=4。第二:我想要计算GridPane TextFields中的总和值,如根据屏幕截图总和将为1+0+0+1+4+0+2+0+1+1+1+2=13。在下一条评论中继续: 3rd:我想用总和计算每行总和的平均值,如第 1 行平均值将是第 1 行平均:第 1 行总和/总和,即第 1 行平均:= 1/13,第 2 行平均:5/13,第 3 行平均:3/13,第 4 行平均 4/13。 4th:正如您在屏幕截图 3 中看到的那样,我想在 GridPane B 文本字段中显示每个平均值,例如 GridPane A row1 平均结果显示在 GridPane B row1 中,GridPane A row2 平均结果显示在 GridPane B row2 中,GridPane A row3 平均结果显示在 GridPane B row3, GridPane A row4 平均结果显示在 GridPane B row4 中。希望这次我的解释清楚。 @Junaid 看了cmets后,觉得上面代码需要的调整很少。我更新了我的答案。立即检查。 @Junaid 很高兴能帮上忙 :) 嗨@Yahya,我需要你的帮助关于this

以上是关于JavaFX:如何从 GridPane 中动态创建的文本字段的值计算平均值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaFX 的 GridPane 中删除“幽灵线”?

子节点的 JavaFX GridPane 动态调整大小以填充分配的区域

如何在 JavaFX 中交换两个 GridPane 节点?

JavaFX中GridPane的行居中对齐

如何在 JavaFX GridPane 的列之间设置填充?

在GridPane JAVAFX中水平居中一行