0

I'm trying to pass values to a GUI for editing through this loop:

public void update(String key) {
    for (int y = 0; y < pixels.length; y++) {
        for (int x = 0; x < pixels[y].length; x++) {
            if (pixels[y][x] == 2) {
                if (key.equals("up")){
                    pixels[y][x] = 1;
                    pixels[y - 1][x] = 2;
                } else if (key.equals("down")) {
                    pixels[y][x] = 1;
                    pixels[y + 1][x] = 2;
                } else if (key.equals("left")) {
                    pixels[y][x] = 1;
                    pixels[y][x - 1] = 2;
                } else if (key.equals("right")) {
                    pixels[y][x] = 1;
                    pixels[y][x + 1] = 2;
                }
            }
        }
    }
    gui.repaint();
}

The key.equals("up") and key.equals("left") branches work without issue, however, key.equals("down") and key.equals("right") do not.

The array I am working with is 25x25:

pixels = new int[][]{ 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, //Center
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 
    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } 
};

The exact error is: Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 25

I have attempted to debug this, but I just cannot figure it out.

Edit: I have updated the code in key.equals("down") and key.equals("right") to be:

pixels[y][x] = 1;
if (y + 1 != 25) {
    pixels[y + 1][x] = 2;
}
pixels[y][x] = 1;
if (x + 1 != 25) {
    pixels[y][x + 1] = 2;
}

However, it gives out a constant output on these two branches (Not wanted), while it doesn't on the other two. Why?

2
  • 5
    What will be the value of y + 1 at the last iteration of your loop? Commented Dec 21, 2013 at 3:01
  • @SotiriosDelimanolis Fixed that in the OP, however, it gives out a constant output now. Commented Dec 21, 2013 at 3:11

1 Answer 1

1

So, you press up, loop through the whole array -- when you hit the center, you "move" the 2 "up" and set the center to 1 -- then you keep iterating through the array of 0s. Fine.

But, you press down instead, the same thing happens -- except that after you "move" the 2 "down" you keep going downwards through the array -- so you find the 2 again, and move it down again -- and so on, until you try to move it past the boundary.

You are thinking that you have a read-consistent view of the array as it was when you started the loop, but you don't. Every change is visible as soon as it is made.

Probably the easiest solution is to retain two copies of the array; read from the first but make changes to the second; then discard the first and make a new copy to process the next keypress.

Sign up to request clarification or add additional context in comments.

3 Comments

Or I could simply use return; and add a gui.repaint(); before that inside those two else if statements, right?
Yeah, I guess that would work, if there will only be a single "2" (which, by the way, if that is the case, why not record its coordinates instead of searching the whole grid for every keypress?)
There are going to be other 2s eventually, I am simply making sure this will work first. Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.