Register events
From Processing
| Versions: | 1.0+ |
| Contributors: | chandler |
| Started: | 2006-03-16 |
Often a processing project contains a number of objects that need to be updated in each draw() cycle. The most common way to handle this is to create an array of objects, then loop through the array in the draw() method and call the appropriate method on each object. This works fine, but wouldn't it be nice if processing could automagically call the draw() method on objects so you wouldn't have to worry about it?
With the addition of the library mechanism, processing exposed a number of new methods intended for library writers, but also available in the environment itself. These register methods offer a way for objects to sign up to “listen” for events and have their corresponding method called automatically. Events available to listeners are:
- pre() called just before draw()
- draw() called at the end of the applet's draw() method
- mouseEvent(MouseEvent e) called when a mouse event occurs
- keyEvent(KeyEvent e) called when a key event occurs
- post() called after draw has completed
- size(int width, int height) called when an applet sets its size
Also, you can see a more detailed listing of the events in the howto.txt in the Processing/library folder. For each of these methods, the applet has a register method to add an object to the list of listeners. For example, say you want your object, foo, to have it's draw() method called automatically on each frame. You just register for the event by doing: this.registerDraw(foo); and processing handles it from there. Things to Watch Out For
First, you must declare you class to be public or else you'll get IllegalAccessExceptions. Second, you must define the draw() method even if it is empty or else the event won't be fired. Also keep in mind that you cannot retrieve the list of objects listening for a specific event so if you need to send some other message to all of your listeners, you'll still need to keep an array around for reference.
Source Code
// grab a reference to the applet. This is used to register the events PApplet app = this; void setup() { size(500,500); background(0); // make the bots for (int i=0; i<1000; i++) { new Bot(); } } // make sure to define the draw method, even if it's empty void draw() { } // create a class, make sure it's declared public public class Bot { float x, y, sx, sy; color c; Bot() { // some random initial properties x = random(1, width); y = random(1, height); sx = random(1, 3); sy = random(1, 3); c = color(random (0, 255),random (0, 255),random (0, 255)); // register with the draw and mouse event using the reference to PApplet // this could also be passed in the constructor etc app.registerDraw(this); app.registerMouseEvent(this); } // called on all bots at the end of each draw() void draw() { x += sx; y += sy; if (x > width || x < 0) { sx *= -1; x += sx*2; } if (y > height || y < 0) { sy *= -1; y += sy*2; } stroke(c); point(x,y); } // called on all bots when a mouse event occurs void mouseEvent(MouseEvent event) { // get the x and y pos of the event int x = event.getX(); int y = event.getY(); switch (event.getID()) { case MouseEvent.MOUSE_PRESSED: // change direction when the mouse is pressed sx = (sx<0)?random(1, 3)*-1:random(1, 3); sy = (sy<0)?random(1, 3)*-1:random(1, 3); break; case MouseEvent.MOUSE_RELEASED: // do something... break; case MouseEvent.MOUSE_CLICKED: // do something... break; case MouseEvent.MOUSE_DRAGGED: // do something... break; case MouseEvent.MOUSE_MOVED: // do something... break; } } }