JavaFx: How to compare values of dynamically created TextFields inside GridPane?

后端 未结 2 1455
星月不相逢
星月不相逢 2021-01-15 03:07

I\'m developing an application using JavaFx in which I\'m creating dynamic TextFields inside a GridPane and there is a Button which is initially disabled like this:

2条回答
  •  情书的邮戳
    2021-01-15 03:45

    Actually it's not that easy to do what you want, because the code you have needs to be refactored (the code is not meant to do such advanced requirements but it's fine for the basic requirements you have). However, you can do something like this:

    First, define a global variable to be updated with the last row index of the invalid TextField (From here you shall conclude that this will change the border color for ONE invalid TextField at a time):

    public static int textFieldIndex = -1;
    

    Now with the help of the method you already have getComponent (int row, int column, GridPane table), create another static method to check if ALL TextFields have Valid Values at one time:

    /**
    * This method to check at run time with every change in any TextField 
    * if the corresponding TextField has a valid value(i.e contains number and
    * the first TextField value is less than the second)
    * @param table
    * @param numRows
    */
    private static boolean hasValidValue(GridPane table, int numRows){
       // cycle through every row in the table
       // and compare every two TextFields
       for(int i=0; i
                Integer.parseInt(((TextField)(getComponent (i, 3, table))).getText())){
                // before returning false
                textFieldIndex = i; // update at which row the TextField is less
                return false;
              }
           }catch(NumberFormatException e){ // if it contains invalid input(non-digit)
                return false;
           }
       }
       return true; 
    }
    

    Now you need to use the above method in the validateTable() method and do some adjustments:

    // pass the comboBox.getValue() to the third parameter
    private void validateTable(GridPane table, Button button, int numRows) {
    
       for(Node textField : table.getChildren()){ 
          if(textField instanceof TextField){
             ((TextField)textField).textProperty().addListener((obs, old, newV)->{
               // first of all remove the red border from the invalid TextField (if any)
              // we know that via textFieldIndex which should be -1 if there is no lesser
              // actually it's a pain 
              if(textFieldIndex!=-1){
                ((TextField) getComponent(textFieldIndex, 3, table)).setStyle("");
              }
              if(isAllFilled(table)){ // if all filled ( you already have this method)
                 if(hasValidValue(table,numRows)){ // check for validity
                    button.setDisable(false); // then make the button active again
                 }
                 else{// if it's not a valid value
                      // re-style the TextField which has lesser value
                     ((TextField) getComponent(textFieldIndex, 3, table)).
                                            setStyle("-fx-border-color: red;");
                      button.setDisable(true); 
                 }
              }
              else{
                   button.setDisable(true);
              }
           });
         }  
       }
    }
    

    Now in your tabPane ChangeListener add the third para to the method (because you already have it you need just to add the value of ComboBox:

    tabPane.getSelectionModel().selectedItemProperty().addListener(new ChangeListener(){
       ....
       ....
       ....
       // I think you have here anchorPane not containerB in the original code
       validateTable((GridPane) containerB.getChildren().get(0), test, comboBox.getValue());
    }
    

    Test

提交回复
热议问题