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:
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