I'm developing an app in JavaFx, in which which I'm dynamically creating TextFeids and CheckBoxes inside GridPane like this:
I'm adding numbers which user will enter in TextField 1 and TextField 2 and displaying in TextField 3 like this using listener:
Problem: What I want is when user will check the CheckBox it should add 10 to the value already present in the TextField 3 of (same row as of triggered CheckBox) and update the text of TextField 3, and when user will uncheck the CheckBox it should subtract 10 from the value present in the TextField 3 of (same row as of triggered CheckBox) and update the text of TextField 3. I tried to do it but it's not working (not adding and removing):
This is how I'm creating GridPane:
public static GridPane table(int rows){
GridPane table = new GridPane();
for(int i=0; i<rows; i++){
TextField textField = new TextField();
textField.setAlignment(Pos.CENTER);
TextField textField2 = new TextField();
textField2.setAlignment(Pos.CENTER);
CheckBox checkBox = new CheckBox("Check Box");
checkBox.setTextFill(Color.WHITE);
checkBox.setAlignment(Pos.CENTER);
TextField textField3 = new TextField();
textField3.setAlignment(Pos.CENTER);
table.add(textField, 0, i);
table.add(textField2, 1, i);
table.add(checkBox , 2, i);
table.add(textField3,3, i);
GridPane.setMargin(textField, new Insets(5));
GridPane.setMargin(textField2, new Insets(5));
GridPane.setMargin(checkBox, new Insets(5));
GridPane.setMargin(textField3, new Insets(5));
}
table.setAlignment(Pos.CENTER);
return table;
}
A method to return a component from Table at specific row and column
public static Node getComponent (int row, int column, GridPane table) {
for (Node component : table.getChildren()) {
if(GridPane.getRowIndex(component) == row &&
GridPane.getColumnIndex(component) == column) {
return component;
}
}
return null;
}
This is how I'm adding:
public void add(GridPane table, int numRows){
for(int i=0; i<numRows; i++){
try {
int valueA = Integer.parseInt(((TextField)(getComponent (i, 0, table))).getText());
System.out.println(valueA);
int valueB = Integer.parseInt(((TextField)(getComponent (i, 1, table))).getText());
System.out.println(valueB);
int add = valueA+valueB;
String addToString = Integer.toString(add);
((TextField)(getComponent (i, 3, table))).setText(addToString);
} catch (NullPointerException e) {
System.out.print("Caught the NullPointerException");
}
}
}
Problem: Addition and subtraction using CheckBox:
public void addPause(GridPane table, int numRows){
for(int i=0; i<numRows; i++){
boolean pause = ((CheckBox)(getComponent (i, 2, table))).isSelected();
int getTextValue = Integer.parseInt(((TextField)(getComponent (i, 3, table))).getText());
int addPause = getTextValue+10;
int removePause = addPause-10;
String addPToString = Integer.toString(addPause);
String removePToString = Integer.toString(removePause);
if (pause) {
((TextField)(getComponent (i, 3, table))).setText(addPToString);
} else {
((TextField)(getComponent (i, 3, table))).setText(removePToString);
}
}
}
This is how I'm triggering using listeners:
for(Node node : table.getChildren()){
if(node instanceof TextField){
((TextField)node).textProperty().addListener((obs, old, newV)->{
add(table, numRows);
});
}
else if(node instanceof CheckBox){
((CheckBox)node).selectedProperty().addListener((obs, old, newV)->{
addPause(table, numRows);
});
}
}
As I suggested in your previous question, just register the listeners for the controls at the point you create them.
You can actually just use a single listener (in each row) for the two text fields and check box, and update the third text box when any of those change. For example:
Now you can get rid of the
add
andaddPause
method, and the chunk of code you posted where you iterate through the child nodes of the grid pane and add listeners. You may be able to get rid of thegetComponent()
method to, unless you need it elsewhere.Here is the code as a SSCCE
and a screenshot:
Since Java is an object-oriented language, it would probably seem more appropriate to do this in an object-oriented way in the first place. I have no idea what data you are representing in this view, but you should define a class that encapsulates the data in a single row:
Then a class to display those data:
and here is some test code:
I moved the styles to the style sheet (
style.css
):One way to achieve that is by adding a
ChangeListener
to everyCheckBox
in theTable(GridPane)
, something like this:Then add this method in the
tabPane ChangeListener
:Test