Weird shifting behavior inside ArrayList - is it a bug?

To start this question off, here’s the code in question:

ArrayList<Integer> x = new ArrayList<Integer>();
ArrayList<Integer> y = new ArrayList<Integer>();
Integer posX;
Integer posY;
Integer posXR;
Integer posYR;
Integer posXLine;
Integer posYLine;
int size = 10;


void draw() {
  background(255);

  //drawing ellipses + lines

  for (int i = 0; i < x.size(); i++) {
    posX = x.get(i);
    posY = y.get(i);
    ellipse(x.get(i), y.get(i), size, size);

    if (i > 0) {
      posXLine = x.get(i-1);
      posYLine = y.get(i-1);
      line(posXLine, posYLine, posX, posY);
    }
  }
}

void mousePressed() {

  //new ellipses

  x.add(new Integer(mouseX));
  y.add(new Integer(mouseY));
}
  

void keyPressed() {

  //removing ellipses

  if (key == 'o') {
    if (x.size() >= 1) {
      posXR = x.get(x.size()-1);
      posYR = y.get(y.size()-1);
      y.remove(posYR);
      x.remove(posXR);
    }


    //troubleshooting

    println("remove");
    println("x: " + x);
    println("y: " + y);
    println("length x: " + x.size());
    println("length y: " + y.size());
    println();
  }
}

The following is supposed to happen:
Whenever you left-click somewhere on the canvas, a new ellipse is drawn at the mouse position, and every ellipse is connected to the ellipse drawn before it by a line. When you press “o”, the last ellipse you drew is removed, as is the line connected to it.

Removing the last ellipse works fine for about 30% of the attempts, but the other 70%, especially when I have 20+ ellipses on the canvas, all the other ellipses sometimes shift to completely different positions.

I tried troubleshooting with the print paragraph at the end of the code, and values inside posXR and/or posYR seem to be removed at random positions inside the lists instead of only the last positions of posXR and posYR, and all values behind them shifted to fill the gap, completely changing the drawn structure.

I’ve been going through the code multiple times now, but there doesn’t seem to be any logical explanation for this behavior.

1 Like

I’m focusing on this:

  if (key == 'o') {
    if (x.size() >= 1) {
      posXR = x.get(x.size()-1);
      posYR = y.get(y.size()-1);
      y.remove(posYR);
      x.remove(posXR);
    }

This code is weird. You get the values of the last things in the lists, and then you are removing things based on that value.

Let’s say you drew your last ellipse at X 550 and Y 600, and you only have 3 ellipses. x.get(x.size()-1) gives you X position of your last ellipse, which is 550, same with Y which is 600. Then you try to remove the (value you just got)-th ellipse out, where (value you just got) is 550 and 600 for both lists. So, you end up trying to remove 550th and 600th elements out of the lists, even if they have only 3 elements.

Obviously, that’s not a really good thing to do.

What happens if you change that part of the code to this?

  if (key == 'o') {
    if (x.size() >= 1) {
      posXR = x.size()-1;
      posYR = y.size()-1;
      x.remove(posXR);
      y.remove(posYR);
    }

Unrelated, but you could also get rid of posXR and posYR values here completely, and connect both if statements into one:

  if (key == 'o' & x.size() >= 1) {
    x.remove(x.size()-1);
    y.remove(y.size()-1);
  }
2 Likes

Connecting the if statements worked, thank you so much! :slight_smile:

Just to make sure you understand the problem, connecting the if statements had nothing to do with this. It was only a suggestion on how to make a code neater - the first suggestion is what worked.