Trouble expanding and writing to array of objects

Hello. Slightly embarrassing, I appear to be having trouble with this class array.

Getting NullPointerException, but I’ve checked by dumping the length of the array to the console, and it’s definitely getting expanded.I’ve tried a few different arrangements with the same result, and don’t understand why I can’t seem to write to the array… I’ve done it many times. Although working with classes is new to me, but I seem to be able to populate my other arrays just fine, so I’m kinda not sure at all what’s wrong.

Reduced code, currently set up in a loop, but I can’t seem to get it to work even if I hard-code a single element. (Not included, but I do have a class ant() that is properly set up as well, and cellXY is also properly set). Hopefully someone can tell me what silly thing I’m not seeing:

int antsPerNest = 10;
int antAmt = 0;
ant[] a;


void setup() {
  a = new ant[0];
}


void setType() {
  a = (ant[]) expand(a, antAmt + antsPerNest);
  for (int i = antAmt; i < a.length; i++) {
    a[i] = new ant(cellXY.x, cellXY.y);
  }
  antAmt+= antsPerNest;
}

Hello. Thank-you. cellXY is already being set correctly. I just did not include that in my minimal paste.

cell[] c;
int cellAmt = cellRows * cellCols;


void setup() {
  c = new cell[cellAmt];
  int i = 0;
  for (int y = 0; y < cellRows; y++) {
    for (int x = 0; x < cellCols; x++) {
      c[i] = new cell((x * cellSize) + (cellSize /2), (y * cellSize) + (cellSize /2));
      i++;
    }
  }
}


class cell {
    PVector cellXY;

cell(float x, float y) {
    cellXY = new PVector(x, y);
  }

}

And this does give the expected output. I know cellXY is being set.

Also, the cellXY variable in the OP is being used within the cell class where it’s set, so there should be no problem with casting. (setType() is a function within the cell class)

your code should be runnable

also, the two codes do not match because in the 2nd code ant doesn’t appear

int antsPerNest = 10;
int antAmt = 0;
ant[] a;
CellXY cellXY=new CellXY(54, 166);

void setup() {
  size(660, 660);
  a = new ant[0];
  setType();
}

void draw() {
  for (ant a1 : a) {
    a1.display();
  }
}

void setType() {
  a = (ant[]) expand(a, antAmt + antsPerNest);
  for (int i = antAmt; i < a.length; i++) {
    cellXY=new CellXY(random(width), random(height));
    a[i] = new ant(cellXY.x, cellXY.y);
  }
  antAmt+= antsPerNest;
}

class CellXY {
  float x, y;

  //constr
  CellXY(float x, float y) {
    this.x = x;
    this.y = y;
  }
}
class ant {

  float x, y;

  //constr
  ant(float x, float y) {
    this.x = x;
    this.y = y;
  }

  void display() {
    //
    circle (x, y, 4);
  }
}

3 Likes

The second code block is not related. It is only there to show the first reply that I have, indeed, set the cellXY variable - As I stated in my OP.

No, my code is not runnable because it’s a reduced code snippet containing the relevant information only. My program does a lot more than shown, and I’m not going to re-write it to try to integrate your methods. That should be un-necessary, and neither does it answer my question.

1 Like

I see your problem with posting code.

The idea is to make a MCVE which should be runnable to demonstrate the problem:

1 Like

Why use ArrayList<> instead of array with append()?

4 Likes

@WhiteSquire ,

Where are you getting a NullPointerException ?

Processing 4.3.4 will show you where. (Newer versions of Processing may not show this.)

@chrisir,

Adding this to your code example shows that the array is increasing and the logic for the small snippet shared with us seems correct:

void keyPressed()
  {
  setType();
  }

Some minimal code from my personal exploration of this topic to update ants in each cell:

Code < Click here to expand!
// Code pieced together from various elements in this topic:
// https://discourse.processing.org/t/trouble-expanding-and-writing-to-array-of-objects/46750

// Some editions were made by glv in the exploration of this.

// A keypress (0 or 1) will increase the number of ants in each cell.
// This can be expanded to fill any number of cells.

int antsPerNest = 1;   // Initial
// int antAmt = 0;     // No longer be global, but per cell

int cellRows = 2;
int cellCols = 2;
int cellAmt = cellRows * cellCols;
int cellSize = 200;
cell[] c;

void setup() {
    c = new cell[cellAmt];
    println(c.length);

    // generate cells
    int i = 0;
    for (int y = 0; y < cellRows; y++) {
        for (int x = 0; x < cellCols; x++) {
            c[i] = new cell((x * cellSize) + (cellSize / 2),
                            (y * cellSize) + (cellSize / 2));
            // println(c[i].cellXY.x, c[i].cellXY.y);
            i++;
        }
    }
    println(i);
}

void draw() {
    // No drawing yet
}

class cell {
    PVector cellXY;
    ant[] antsInCell;      // Array to hold ants for this specific cell
    int currentAnts = 0;   // Counter for ants in this cell

    cell(float x, float y) {
        cellXY = new PVector(x, y);
        antsInCell = new ant[0]; // Initialize with an empty array
    }

    // setType() function moved into the cell class
    void setType() {
        antsInCell = (ant[]) expand(antsInCell, currentAnts + antsPerNest);

        // For examining output:
        println("Expanded:");
        debug(antsInCell);

        for (int j = currentAnts; j < antsInCell.length; j++) {
            // Spawn ants randomly within the cell's boundaries
            antsInCell[j] = new ant(
                random(cellXY.x - cellSize / 2, cellXY.x + cellSize / 2),
                random(cellXY.y - cellSize / 2, cellXY.y + cellSize / 2)
            );
            println("Added:", j, antsInCell[j].antXY.x, antsInCell[j].antXY.y);
        }
        currentAnts += antsPerNest;

        // For examining output:
        println("Updated:");
        debug(antsInCell);
    }
}

class ant {
    PVector antXY;

    ant(float x, float y) {
        antXY = new PVector(x, y);
    }
}

void keyPressed() 
  {
    if (key == '0') {
      println("Cell 0:");
        c[0].setType(); // Call setType on the first cell
        
    }
    else if (key == '1') {
        println("Cell 1:");
        c[1].setType(); // Call setType on the second cell

    }
    // Extend as needed...
  }

// Debug and examining objects for nulls
void debug(ant[] arr) {
    for (int n = 0; n < arr.length; n++) {
        if (arr[n] == null) {                           //object     
            println("null");
        } else {
            println(n, arr[n].antXY.x, arr[n].antXY.y); //element
        }
    }
    println();
}

The full code (not shared) displayed ants per cell and updated with keyPressed():

Sharing with the community!
I also had errors and NullPointerException along the way and sorted these out with some troubleshooting and experience.
There may be something in there of interest.

:)

1 Like