We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › How to create objects on-the-fly
Page Index Toggle Pages: 1
How to create objects on-the-fly? (Read 1043 times)
How to create objects on-the-fly?
Aug 8th, 2008, 12:39am
 
I'm trying to figure out how to create an object on-the-fly, meaning while a program is running, after setup() has already run.  In the sample code below, I'm trying to create a new "mrect" object whenever the mouse is clicked.  So, the program starts out with an mrect.length of only 1, but hopefully, upon each mouse click, that number is incremented.

I've used arrays of objects before, but it seems that creating a new object is not really as simple as appending a new value to the array.  Should it be?  

Copy and paste the following into a new sketch and it will run.  Then try uncommenting the two lines I have commented out in mousePressed(), one at a time.  Those are the two methods I have tried to append/expand the array.  What am I doing wrong?  What is the syntax for adding a new object to an object array and initializing it at the same time?

Thanks!

Code:
MRect[] mrect = new MRect[1];

void setup()
{
size(500, 500);
fill(255, 150);
noStroke();
mrect[0] = new MRect(1, 50, 0.25, 0.01*height); //Initialize the first mrect
}

void draw()
{
background(0);
for (int i = 0; i < mrect.length; i++) { //Loops through all mrect objects
mrect[i].display();
}
for (int i = 0; i < mrect.length; i++) { //Loops through all mrect objects
mrect[i].move(mouseX, mouseY, 30);
}
}

void mousePressed() {
MRect[] mrectNew = new MRect[1];
mrectNew[0] = new MRect(5, 200, 50, 0.2*height);
//mrect = append(mrect, mrectNew); //Triggers "ype of the right sub-expression, "java.lang.Object", is not assignable to the variable" error
//MRect[] mrect = (MRect[]) expand(mrect); //Triggers "var may be accessed before having been definitely assigned a value" error
println(mrect.length);
}

class MRect
{
int w; // single bar width
float xpos; // rect xposition
float h; // rect height
float ypos ; // rect yposition
float d; // single bar distance

MRect(int iw, float ixp, float ih, float iyp) {
w = iw;
xpos = ixp;
h = ih;
ypos = iyp;
println("created new object");
}

void move (float posX, float posY, float damping) {
float dif = ypos - posY;
if (abs(dif) > 1) {
ypos -= dif/damping;
}
dif = xpos - posX;
if (abs(dif) > 1) {
xpos -= dif/damping;
}
}

void display() {
rect(xpos + (w*10), ypos, w, height*h);
}
}
Re: How to create objects on-the-fly?
Reply #1 - Aug 8th, 2008, 2:23am
 
void mousePressed() {  
 MRect mrectInstance = new MRect(5, 200, 50, 0.2*height);
 mrect = (MRect[]) append(mrect, mrectInstance);
}

See the Processing reference for append(). You pass the array you want expanded as the first argument; the individual element instance as the second.

You also need to explicitly cast the append return type to that of your mrect variable with (MRect[]), otherwise you will get a type assignment error because append() returns Object, not MRect[].
Re: How to create objects on-the-fly?
Reply #2 - Aug 8th, 2008, 2:54am
 
Awesome!  Thanks so much.  I had seen the documentation on append(), but guess I misinterpreted it.  Thank you for explaining so clearly why I need to include the "casting" step.

BONUS QUESTION:  Is it possible to destroy/delete objects in a similar fashion?
Re: How to create objects on-the-fly?
Reply #3 - Aug 8th, 2008, 2:55am
 
Also:  Can I start out the object array with zero elements in the array (zero objects)?  The example I posted above starts with one.  Thanks.
Re: How to create objects on-the-fly?
Reply #4 - Aug 8th, 2008, 4:58am
 
See:

http://processing.org/reference/shorten_.html

http://processing.org/reference/subset_.html

In general, see "Array Functions" here:

http://processing.org/reference/index.html

In Java (the underlying language of Processing), you cannot change the length of an array once you initialize it. A zero length array would not have much use. The Processing append() API takes an array and an element and returns you a *different* array one larger than the one you gave it with the contents of the array you passed plus the element in the last position of the new array.

Since you set your global mrect variable to this new array by setting it to the result of append(), the old array becomes "dereferenced" from your sketch, but it still exists for some time in memory until the Java Virtual Machine running your Processing sketch garbage collects it (clears it from memory to free up space for new objects).
Re: How to create objects on-the-fly?
Reply #5 - Aug 9th, 2008, 2:55pm
 
Might now be the time to learn about ArrayLists?

Here's an example:

Code:

// Magic expanding array declared here
ArrayList points;
// To operate on an item in an ArrayList we need a dummy object
Point tempPoint;
// Read tin
void setup(){
size(200, 200);
points = new ArrayList();
}
// Loop
void draw(){
background(255);
for(int i = 0; i < points.size(); i++){
// use the dummy object to look inside the ArrayList
tempPoint = (Point)points.get(i);
// now manipulate that object
tempPoint.x = (tempPoint.x + 2) % width;
point(tempPoint.x, tempPoint.y);
}
}
// Add some Points to the ArrayList on each mouse click
void mousePressed(){
for(int i = 0; i < 10; i++){
points.add(new Point(random(width), random(height)));
}
}
// Generic little class
class Point{
float x, y;
Point(float x, float y){
this.x = x;
this.y = y;
}
}


You can also use the remove() function of an ArrayList to shorten the ArrayList. This is much faster way of managing a stack of objects that's always changing. Plus it's a lot easier to perform Jenga-style operations where you destroy objects in the middle of the ArrayList.

Alternatively you could have an extra large array to accomodate all the possible objects. Then you would manage the contents intelligently (which is kinda what ArrayList is doing for you). But that's something you do when you're trimming code down for even more speed.
Re: How to create objects on-the-fly?
Reply #6 - Aug 9th, 2008, 11:28pm
 
Thanks, smith, for that uncommonly clear explanation of how Processing manages arrays.  Now it makes sense why you have to use the structure array = append(array, newArrayObjectToBeAppended).

I asked about having a zero length array because it would be useful for my project.  Rather than creating the array with one initial, "dummy" element, it would be easier to create a zero length array, and then only add the "real" data elements to it as needed.

Also, st33d, thanks for that example.  I think ArrayLists would be better for my purposes.  In one particular project, I don't want to have to have a fixed maximum number of objects.  (It's a data visualization project, where there could be either tens or thousands of data points, so I want to be able to add and remove them as needed, on-the-fly.)

Thanks again to you both for your help.
Page Index Toggle Pages: 1