I was recently forced to draw a graph from an android thread and much to my surprise it worked. I was under the impression that all drawing had to be done with draw() and, in fact, Processing documentation explicitly states:
You cannot draw to the screen from a function called by thread().
The following demo shows that it can be done, provided you use a single stroke color and minimal use of draw() for other purposes. Note that each thread has a unique timer interval.
/*
Plots data in three rectangles ("channels") simultaneously using a different
thread with unique timer interval for each channel. For best results, use a
single stroke color and minimal use of draw(). noStroke() may not be honored.
Suggest LANDSCAPE for tablets and PORTRAIT for smaller devices.
*/
boolean stopPlot;
int x = 0;
int y = 0;
int y1 = 0;
int i = 0;
int j = 0;
int j1 = 0;
int m = 0;
int n = 0;
int n1 = 0;
long Timer1 = 0;
long Timer2 = 0;
long Timer3 = 0;
final int Interval_10 = 10;
final int Interval_50 = 50;
final int Interval_100 = 100;
final int Interval_1000 = 1000;
final int _stopBtnX = 30;
final int _stopBtnY = 30;
final int _stopBtnW = 150;
final int _stopBtnH = 60;
class StopBtn {
void display(){
fill(151,186,66,255); // background color - GREEN
noStroke();
rect(_stopBtnX, _stopBtnY, _stopBtnW, _stopBtnH, 15);
fill(0); // text color
textSize(42);
text("Stop", _stopBtnX + 20, _stopBtnY + 15, _stopBtnW, _stopBtnH);
}
void press() {
if(stopPlot){
stopPlot = false;
} else {
stopPlot = true;
exit();
}
println("stopPlot = ", stopPlot);
}
}
StopBtn stopBtn;
void setup() {
background(0, 0, 200); // blue
// Recommended for tablets
orientation(LANDSCAPE);
// Recommended for smaller devices
// orientation(PORTRAIT);
stopBtn = new StopBtn();
stopBtn.display();
stopPlot = false;
thread("plot1");
thread("plot2");
thread("plot3");
colorMode(HSB, 360, 100, 100);
// plot1 rectangle
noStroke();
fill(166,118,60);
rect(0,height - 350, width, 350);
// plot2 rectangle
noStroke();
fill(218);
rect(0,height - 700, width, 350);
// plot3 rectangle
noStroke();
fill(180, 42, 50);
rect(0, height - 1050, width, 350);
}
void draw() {
}
void plot3() {
while (!stopPlot) {
if (millis() >= Timer3) {
Timer3 += Interval_50;
n += 8;
if (n > 256) {n = 0;}
stroke(255);
strokeWeight(6);
line(m, height - 750 - n, m++, height - 750 - n1);
n1 = n;
m += 5;
if (m > width) {
m = 0;
noStroke();
fill(180, 42, 50);
rect(0,height - 1050, width, 350);
}
}
}
}
void plot2() {
while (!stopPlot) {
if (millis() >= Timer2) {
Timer2 += Interval_100;
j += 8;
if (j > 256) {j = 0;}
stroke(255);
strokeWeight(6);
line(i, height - 400 - j, i++, height - 400 - j1);
j1 = j;
i += 8;
if (i > width) {
i = 0;
noStroke();
fill(218);
rect(0,height - 700, width, 350);
}
}
}
}
void plot1() {
while (!stopPlot) {
if (millis() >= Timer1) {
Timer1 += Interval_10;
y += 8;
if (y > 256) {y = 0;}
stroke(255);
strokeWeight(6);
line(x, height - 50 - y, x++, height - 50 - y1);
y1 = y;
x++;
if (x > width) {
x = 0;
noStroke();
fill(166,118,60);
rect(0,height - 350, width, 350);
}
}
}
}
void mousePressed(){
if((mouseX >= _stopBtnX) && (mouseX <= _stopBtnX+_stopBtnW) && (mouseY >= _stopBtnY) && (mouseY <= _stopBtnY+_stopBtnH)){
stopBtn.press();
}
}