Reputation: 31
I have 81 textFields (textField_0 ... textField_80) that I want to populate my array with. How can I increase the textField number through each iteration of the for loop
I'm looking for something like this
for (x=0 ; x<=80 ; x++) {
grid[x] = Integer.parseInt(textField_x.getText());
}
Having textField_x doesn't work, because it's obviously looking for a textField called textField_x, so what would be the correct way of doing this?
EDIT: I've tried the solution Würgspaß provided, however now I need to implement it into my frame. As a test I tried this
fields[1].setColumns(10);
fields[1].setBounds(310, 300, 32, 32);
frame.getContentPane().add(fields[1]);
But it does not show up in my windowbuilder
Upvotes: 0
Views: 153
Reputation: 4820
You cannot use a variable identifier in Java. For your approach to work change your code to create the TextFields like this:
public final static int NUM_FIELDS = 81;
TextField[] fields = new TextField[NUM_FIELDS];
for (int x=0 ; x<NUM_FIELDS ; x++) {
fields[x] = new TextField();
}
and retrieve contents like this:
for (int x=0 ; x<NUM_FIELDS ; x++) {
grid[x] = Integer.parseInt(fields[x].getText());
}
However, using 81 text fields is quite cumbersome, I would say. For my Sudoku solver I used a JTextArea for the user to type in the figures line by line. The code (in short form) looked something like this:
//number of fields of Sudoku
public final static int NUM_FIELDS = 81;
//ascii value for zero
public final static int ASCII_ZERO = 48;
//Sudoku figures to be entered by GUI user
private final JTextArea field;
[...]
//code to retrieve input
byte[] bytes = field.getText().getBytes();
int[] figures = new int[NUM_FIELDS];
for (int c = 0, i = 0; c < bytes.length; c++) {
if (bytes[c]>=ASCII_ZERO && bytes[c]<(ASCII_ZERO+10)) {
figures[i++] = (bytes[c] - asciiNull); //store entered value as int in array
}
//ignore newline characters but optionally handle wrong input by user using else-statements
}
Of course, you could also use a two-dimensional array like int[9][9]
or convert the entered text using Integer.parseInt
with appropriate error handling, but in anyway you have to care about just one GUI element.
Upvotes: 3
Reputation: 5331
I agree with the other chaps here in that putting these into an array and then iterating through is the be better way to do it. However, there is a way to do this via reflection.
Lets say that I have 100 JTextField
named as follows:
JTextField tf_0 = new JTextField("0");
JTextField tf_1 = new JTextField("1");
JTextField tf_2 = new JTextField("2");
Up to JTextField tf_99
.
I can then do as follows. First, I reflect the class to get its fields. Then I filter them based on their class, then the name they start with, then sort them (you may want a string comparator which goes in numeric order, rather than the default alphabetical order à la 19, 2, 20, 21).
It then creates an array and populates it with the relevant values. (You could make this all happen in streams using mapToInt
, but that introduces a try-catch that I don't want to bother with.)
private int[] getTextFieldValues() throws IllegalArgumentException, IllegalAccessException {
List<Field> fields = Stream.of(this.getClass().getDeclaredFields())
.filter(f -> f.getType().equals(JTextField.class))
.filter(f -> f.getName().startsWith("tf_"))
.sorted((f1, f2) -> f1.getName().compareTo(f2.getName()))
.collect(Collectors.toList());
int[] output = new int[fields.size()];
for (int i = 0; i < fields.size(); i++) {
JTextField jtf = (JTextField) fields.get(i).get(this);
output[i] = Integer.parseInt(jtf.getText());
}
return output;
}
Now, this approach is slower, less efficient, and ... quite simply, not preferable in any way. It also requires that the fields have predictable names and that the only ones with a name starting with tf_
are the droids fields you are looking for (or, just change or add the filtering mechanisms). But it does achieve what you want it to do.
Upvotes: 1
Reputation: 21
Instead of storing them in 81 different variables, go store them in one array directly.
Upvotes: 2