Executive Summary: noLoop/redraw cannot be used in the same code block correctly. The redraw needs to be in another code block, such as that for a separate event.
Yesterday's difficulty with loop/noLoop/redraw caused me to look into the Processing book, look at the javadocs and the Processing code itself, and all of the example Sketches.
I'm still puzzled, but possibly I've found the answer: apparently redraw() can not be called within code blocks that use noLoop(). It can be called in other event code.
To test this, I modified the code in the Redraw and Loop examples:
File>Examples>Basics>Structure>Redraw/Loop
These examples draw horizontal lines, using the mouse pressed event to either draw another line (ReDraw example) or to change from noLoop() to loop() mode (Loop example).
I first made a simple change: each mouse click flipped the loop mode. I.e. one click starts the line animating, the next halts it. I also added a keyPressed which calls redraw, but only if the animation is in noLoop mode. Finally, I added a flag, testNoLoopRedraw, which adds a pause and redraw to the noLoop branch of mousePressed. That's the code below.
Note that when draw() is called immediately following the noLoop() in setup(), it should draw a red line, with subsequent lines being red or white depending whether or not called in a noLoop mode. ( The noLoop in setup causes draw to be called only once, see pg 236 in book or http://processing.org/reference/noLoop_.html )
This code seems to work as expected: the mousePressed toggles the animation, and the keypressed draws one red line while in noLoop mode. Cool!
I then wanted to use noLoop and redraw together. Just change testNoLoopRedraw to true. Now noLoop branch in mousePressed not only causes the animation to halt, it also uses redraw, after a second's delay, to draw one more line.
This has VERY odd results: the mousePressed redraw does take effect, but it does not draw a red line as it should! For some reason, it does not see the amLooping flag correctly. The keyPressed code works correctly, it draws a red line (make sure to wait 1 second after the mousePressed).
I'm a bit spooked by all this, but it leads me to believe that redraw cannot correctly be used within the same block as noLoop.
Is this a bug? Standard behavior? Me being a dummy!? Is there a work-around?
Code:
boolean testNoLoopRedraw = false;
boolean amLooping; // Avoid PApplet's "looping" variable
float y = 100;
void setup() {
size(200, 200);
amLooping=false;
noLoop();
}
void draw() {
stroke(amLooping?255:color(255,0,0));
background(0);
line(0, y, width, y);
y = (y + 1)%height;
}
void keyPressed() {
if (!amLooping) {
redraw();
}
}
void mousePressed() {
amLooping = !amLooping;
if (amLooping) {
loop();
} else {
noLoop();
if(testNoLoopRedraw) {
delay(1000); // lets you see line move
redraw(); // calls draw, but draw thinks amLooping=true!
}
}
}