How to add a new item in a arraylist when this class is defined by myself?

I defined a class named (drop) to represent a moving cloud with rain. And then I created an array uninitialized named (drops[]) to represent a list will increase automatically with ‘for loop’ in a table.
But when using append to add the new drop, the feed back told me that Type mismatch, “java.lang.Object” does not match with “sketch_220516a.drop[]”.
Anyone helps me?
I’m a Chinese, not very good at English, if this description isn’t clear. Here is the code:

useful part only in “draw()”

//public_variable_____________________________________________________________
PImage watch, dwr;
Table table;
float p, w;
int year = 2021;
//set_map______________________________________________________________________
void setup() {
table = loadTable(“beijing.csv”, “header”);
size(1000, 1000);
background(255);
PFont cityFont;
dwr = loadImage(“dwr.png”);
cityFont = loadFont(“Anton-Regular-32.vlw”);
PFont numFont;
numFont = createFont(“andalemo.ttf”, 12);
textAlign(CENTER);

int circlenum = 6, circledist = 80;
String city = “BeiJing\nChina”;
pushMatrix();
translate(width/2, height/2);

for (int i=0; i<circlenum; i++) {
strokeWeight(1);
if (i==2) {
strokeWeight(3);
}
noFill();
stroke(220);
circle(0, 0, 150+icircledist);
}
strokeWeight(30);
stroke(255);
line(0, height/2, 0, 0);
strokeWeight(18);
line(0, -200, 0, 0);
strokeWeight(1);
stroke(220);
fill(220);
line(0, -203, 0, -283);
quad(0, -282, 40, -278, 0, -290, -40, -278);
textFont(numFont);
for (int i=0; i<circlenum; i++) {
strokeWeight(2);
if (i==2) {
strokeWeight(3);
}
fill(200);
text(str(-20+i
10)+“°C”, 0, (150+i*circledist)/2+5);
}
strokeWeight(5);
textFont(cityFont, 34);
text(city, 0, -8);
textFont(cityFont, 14);
text(“RH”, 0, -70);
text(“70”, 0, -108);
text(“40”, 0, -148);
text(year, 0, -300);
triangle(-2, -195, -8, -197, -8, -193);
String[] mon = {“Jan.”, “Feb.”, “Mar.”, “APR.”, “May.”, “Jun.”, “Jul.”, “Aug.”, “Sept.”, “Oct.”, “Nov.”, “Dec.”};
rotate(-PI/2+0.3);

for (int i = 0; i<12; i++) {
translate(300, 0);
rotate(PI/2);
textSize(20);
text(mon[i], 0, 0);
rotate(-PI/2);
translate(-300, 0);
rotate(2*PI/12);
}

float t, s, at;

for (int i= 1; i<365; i++) {
t = table.getRow(i).getFloat(“T”);
p = table.getRow(i).getFloat(“P”);
s = table.getRow(i).getFloat(“S”);
w = table.getRow(i).getFloat(“W”);
at = table.getRow(i).getFloat(“AT”);
year = 2021;
//year = table.getRow(i).getInt(“y”);

//RH first
translate(180, 0);
strokeWeight(2);
noFill();
translate(-s/2, 0);
stroke(255-s/3);
line(0, 0, -s/2, 0);
translate(s/2, 0);
translate(-180, 0);
//temp second

strokeWeight(2);
translate(150, 0);
//colorRank
if (t>32) stroke(240, 52, 52);//hong
if (t<32) stroke(255, 149, 38);//cheng
if (t<28) stroke(255, 230, 0);//huang
if (t<25) stroke(20, 218, 51);//lv
if (t<22) stroke(175, 255, 34);//huanglv
if (t<19) stroke(10, 220, 186);//qinglv
if (t<11) stroke(10, 170, 220);//tianlan
if (t<0) stroke(34, 178, 255);//bing
if (t<-5) stroke(34, 138, 255);//lan
if (t<-10) stroke(34, 101, 255);//
if (t<-15) stroke(54, 42, 211);
if (t<-20) stroke(99, 42, 211);

line(4*at, 0, 4*t, 0);

translate(-150, 0);
rotate(2*PI/365);

}
popMatrix();
noStroke();
pushMatrix();
translate(width/2, height/2);
fill(0, 10);
rectMode(CENTER);
rect(0, 0, 1000, 1000);
rect(0, 0, 780, 780, 50);
rect(0, 0, 790, 790, 50);
popMatrix();
save(“iwatch.png”);
watch = loadImage(“iwatch.png”);

frameRate(2);//2 pics per second

imageMode(CENTER);
pointer(width/2, height/2, 0);
}
float temp = 1;
drop[] drops;
drop d1;

boolean temp2 = false;

//start_loop___________________________________________________________________________

void draw() {
//loading frame
tint(255, 60);
if (temp==1) delay(2000);
//looping rain and cloud
for (TableRow row : table.rows()) {
index++;
float flowr0, angle, x0, y0;

image(watch, width/2, height/2);
pushMatrix();
temp = pointer(width/2, height/2, temp);
popMatrix();
delay(40);

p = row.getFloat("P");
w = row.getFloat("W");


if (p>=25) flowr0 = 50;
if (p<25)  flowr0 = 35;
if (p<10)  flowr0 = 20;

angle = w/360;
x0 = 500*cos(angle);
y0 = 500*sin(angle);

drops = append(drops, new drop(x0, y0, -5, 5, flowr0));


for (drop drop : drops) {
  if (drop.update())
    drop.update();
}


if (mousePressed) {
  d1 = new drop(random(500, 1000), random(0, 500), -5, 5, random(10, 50));
  temp2 = true;
}

while (temp2) {
  temp2 = d1.update();
}






if (keyPressed) exit();

}
}

//define_function____________________________________________________________________

float pointer (float x, float y, float i) {
translate(x, y);
rotate((i/300)-PI/2);
noStroke();
fill(255);
circle(0, 0, 10);
quad(-30, 0, 20, 3, 390, 0, 20, -3);
return i+1;
}

//define_class_drop_and_cloud________________________________________________________

class drop {
PVector s, v;
float flowr;
drop (float x2, float y2, float vx2, float vy2, float f2) {
s = new PVector(x2, y2);
v = new PVector(vx2, vy2);
flowr = f2;
}

drop (PVector s1, PVector v1, float f1) {
s = s1;
v = v1;
flowr = f1;
}
boolean update() {
s.add(v);
flowr = flowr*0.85;
tint(200, 60);

image(dwr, s.x, s.y, 3*flowr, 3*flowr);

//fill(51,102,153);
//circle(s.x,s.y,flowr);
//println("alive");
if (flowr<5) return false;
return true;

}
}

I can’t test your code for myself but try

drops= (drop[]) append(drops, new drop(x0, y0, -5, 5, flowr0));

(I’ll explain it in another comment)

1 Like

Basicly append returns an Object. Processing however doesn’t know it is an array by casting it to (drop[]) you tell Processing that the object returned is in fact an array.

Another thing you could use are ArrayList. It works simular to an array so you can use.

ArrayList<drop> list;
void setup(){
list=new ArrayList();
}

to create your list. You can simply use

list.add(new drop(...));

to “append” your list. To access an element simular to array[i] you can use list.get(i)
to override it you can use list.set(i,..some object...).

I hope I could help you!

(PS: Should you want to stick with append you can add this method to avoid the problem with casting to arrays alltogether

<T> T[] append(T[] array, T... appended) {
  ArrayList<T> lst=new ArrayList();
  for (int i=0; i<array.length; i++) lst.add(array[i]);
  for (int i=0; i<appended.length; i++) lst.add(appended[i]);
  return (T[]) lst.toArray();
} 

It also this also allows appending an array with more than one element so things like

append(new Integer[]{4,1,2},3,6,1)

Make an array with 4,1,2,3,6,1 now.)

2 Likes

thanks very much!:saluting_face:I use your second method and solve it. Arraylist is a very convenient way for this situation.

Here’s another alternative append() based on Arrays.copyOf():

static final <T> T[] append(T[] array, final T value) {
  array = expand(array, array.length + 1);
  array[array.length - 1] = value;
  return array;
}

static final <T> T[] expand(final T[] list) {
  return expand(list, list.length << 1);
}

static final <T> T[] expand(final T[] list, final int newSize) {
  return java.util.Arrays.copyOf(list, newSize);
}

Those are from a very old refused pull request I’ve done almost a decade ago:

2 Likes

I combined both versions of the append methods into something one can put into a sketch with the posibility to append the array with multiple elements.

<T> T[] append(T[] array, T... appended) {
  T[] ret=java.util.Arrays.copyOf(array, array.length+appended.length);
  for(int i=0;i<appended.length;i++) ret[array.length+i]=appended[i];
  return ret;
} 

That would be cancat() instead; which would be faster w/ arrayCopy():

static final <T> T[] concat(final T[] a, final T... b) {
  final T[] c = expand(a, a.length + b.length);
  System.arraycopy(b, 0, c, a.length, b.length);
  return c;
}

static final <T> T[] append(T[] array, final T value) {
  array = expand(array, array.length + 1);
  array[array.length - 1] = value;
  return array;
}

static final <T> T[] shorten(final T[] list) {
  return expand(list, list.length - 1);
}

static final <T> T[] expand(final T[] list) {
  return expand(list, list.length << 1);
}

static final <T> T[] expand(final T[] list, final int newSize) {
  return java.util.Arrays.copyOf(list, newSize);
}