Answer the question
In order to leave comments, you need to log in
How to repaint a canvas in a loop?
There is a canvas that calls repaint in an endless loop. When repainting the canvas, a random color is set.
Expectation: the canvas should change colors constantly, (at the moment, 1 iteration of the loop is fast, then it will be processed for about 1-2 seconds).
Reality: the color of the canvas is not updated. If you make not an infinite loop, but a final one, visually the canvas will be updated as soon as this loop ends.
How do I make the canvas update visually as it cycles?
Below is a callback that is called in a loop (update() method - repaint() + setting color before repaint):
public void redrawCanvas (Color color) {
System.out.println(color.getRed() + ", " + color.getGreen() + ", " + color.getBlue());
this.renderCanvas.update(color);
this.renderWindow.repaint();
}
private void renderButtonHandler (ActionEvent event) {
RenderThreadsController renderThreadsController = new RenderThreadsController(this::redrawCanvas);
renderThreadsController.run();
}
public void redrawCanvas (Color color) {
System.out.println(color.getRed() + ", " + color.getGreen() + ", " + color.getBlue());
this.renderCanvas.update(color);
this.renderWindow.repaint();
}
public class RenderThreadsController implements Runnable {
final private int threadsCount = 8;
private ExecutorService executorService;
private List<Future<int[]>> threadsPool;
private int currentSample = 1;
private RedrawCanvas callback;
RenderThreadsController(RedrawCanvas callback) {
Thread thread = new Thread(this);
thread.start();
this.executorService = Executors.newCachedThreadPool();
this.threadsPool = new ArrayList<>();
this.callback = callback;
}
public void run() {
for (int i = 0; i < this.threadsCount; i++) {
this.threadsPool.add(
this.executorService.submit(
new RenderThread(
this.currentSample++
)
)
);
}
int t = 20;
/*while (t > 0) {
this.startThread();
t--;
}*/
while (this.threadsPool.size() > 0) {
this.startThread();
}
executorService.shutdown();
}
private void startThread () {
try {
Future<int[]> thread = this.threadsPool.get(0);
int[] color = thread.get();
this.callback.redrawCanvas(new Color(color[0], color[1], color[2]));
this.threadsPool.remove(0);
this.threadsPool.add(
this.executorService.submit(
new RenderThread(
this.currentSample++
)
)
);
} catch (InterruptedException|ExecutionException e) {
e.printStackTrace();
}
}
}
Answer the question
In order to leave comments, you need to log in
Most likely, your cycle is running in the rendering thread and, thus, while the calculations are in progress in the cycle, the rendering thread is blocked. If the loop ends, then the rendering will be executed. Try to isolate the logic for changing parameters and forcing a draw call in a separate thread.
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question