Lachlan Langmead
Lachlan Langmead

Reputation: 31

Increasing a textField number in a for loop

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

Answers (3)

W&#252;rgspa&#223;
W&#252;rgspa&#223;

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

ifly6
ifly6

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

Elio
Elio

Reputation: 21

Instead of storing them in 81 different variables, go store them in one array directly.

Upvotes: 2

Related Questions