了JavaFx:如何验证mutilple的TextField在运行时创建?(JavaFx: How

2019-09-27 17:20发布

我使用的for循环,并将它们添加到里面Gridpane(其中有8列)这样在运行时创建多个的TextField:

public static GridPane table(int rows){
            GridPane table = new GridPane();

            for(int i=0; i<rows; i++){
            JFXTextField textField1 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField2 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField3 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField4 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField5 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField6 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField7 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);
            JFXTextField textField8 = new JFXTextField();
            textField1.setAlignment(Pos.CENTER);

            //add them to the GridPane
            table.add(textField1, 0, i+1);
            table.add(textField2, 1, i+1);
            table.add(textField3, 2, i+1);
            table.add(textField4, 3, i+1);
            table.add(textField5, 4, i+1);
            table.add(textField6, 5, i+1);
            table.add(textField7, 6, i+1);
            table.add(textField8, 7, i+1);
         }
        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;
     }

问题就在这里:我想验证每一个文本字段,所以如果用户忘记在任何文本字段的写,我想禁用按钮,为此,我用这样的绑定:

 private void validatingGrid() {
        GridPane table = (GridPane) anchorPane().getChildren().get(0);

        for(int i=1 ; i<=comboBox().getValue(); i++){
            JFXTextField text0 = ((JFXTextField)getComponent (i, 0, table));
            JFXTextField text1 = ((JFXTextField)getComponent (i, 1, table));
            JFXTextField text2 = ((JFXTextField)getComponent (i, 2, table));
            JFXTextField text3 = ((JFXTextField)getComponent (i, 3, table));
            JFXTextField text4 = ((JFXTextField)getComponent (i, 4, table));
            JFXTextField text5 = ((JFXTextField)getComponent (i, 5, table));
            JFXTextField text6 = ((JFXTextField)getComponent (i, 6, table));
            JFXTextField text7 = ((JFXTextField)getComponent (i, 7, table));

                button.disableProperty().bind(
                        Bindings.isEmpty(text0.textProperty())
                        .or(Bindings.isEmpty(text1.textProperty()))
                        .or(Bindings.isEmpty(text2.textProperty()))
                        .or(Bindings.isEmpty(text3.textProperty()))
                        .or(Bindings.isEmpty(text4.textProperty()))
                        .or(Bindings.isEmpty(text5.textProperty()))
                        .or(Bindings.isEmpty(text6.textProperty()))
                        .or(Bindings.isEmpty(text7.textProperty()))
                    );
                }
     }

但是,发生了什么是它仅在验证最后一排,让我们说,如果我创建3行中Gridpane textfeilds的,所以它只是验证第三排没有第一和第二行和第三行条目的基础上,它的启用按钮,但我想以后确认所有应启动按钮,否则不能行。 请帮我,我怎么能做到这一点。

Answer 1:

您绑定的逻辑是正确的。 然而,由于该问题的for loop [ for(int i=1 ; i<=comboBox().getValue(); i++) ],它废墟的工作。 所有TextFields是在列索引 0和唯一的变化是行索引 。 所以,你应该使用getComponent(i, 0, table); 所有TextFieldsfor loop不改变列索引 12 ..等。 但也因为每一次循环中,您要指定ALL不会解决问题TextFields相同的索引 ,然后将其覆盖在每一个循环,直到它们都指向TextField的指数comboBox().getValue()和列0 (这就是为什么它的工作的最后一排,你所提到的)。

我会建议不同的方法,像这样:

首先你需要一个方法来检查是否所有其它TextFields填充/不为空:

/**
* Check if all the TextFields are filled and not empty
* @param table
*/
 private static boolean isAllFilled(GridPane table){
    for(Node node : table.getChildren()){ // cycle through every component in the table (GridPane)
        if(node instanceof TextField){ // if it's a TextField
        // after removing the leading spaces, check if it's empty
            if(((TextField)node).getText().trim().isEmpty()){
                    return false; // if so, return false
            }
        }       
    }
    return true;
 }

其次,听文本更改为每一个TextField的表,并与每一个变化,检查是否所有其它TextField被填充/不为空:

/**
* To Validate the Table (GridPane)
* This method should be added to the tabPane change listener
* @param table
* @param button
*/
private void validateTable(GridPane table, Button button) {

   for(Node node : table.getChildren()){ // cycle through every component in the table (GridPane)
      if(node instanceof TextField){ // if it's a TextField
        ((TextField)node).textProperty().addListener((obs, old, newV)->{ // add a change listener to every TextField
        // then check if the new value is not empty AND all other TextFields are not empty
          if(!newV.trim().isEmpty()&&isAllFilled(table)){ 
             button.setDisable(false); // then make the button active again
          }
          else{
              button.setDisable(true); // or else, make it disable until it achieves the required condition 
          }
      });
   }    
}

此外,您还需要设置按钮,在创建后禁用一次。

Button button = new Button("Test"); 
button.setDisable(true);

最后,你需要添加的方法在tabPane变化监听块:

tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>(){
      .........
      .........
      .........
      validateTable((GridPane) anchorPane().getChildren().get(0), test);
}

测试



文章来源: JavaFx: How to validate mutilple TextFields creating at run time?