Java App UI Animation: How to synchronize the paint function inside a Displayable?

Hi,

I’m trying to display a small animation on the screen and I’m having trouble to synchronize the paint with the drawing on board.

My first attempt was to wait with a Thread sleep:

while (true) {
main.repaint();
main.update();
Thread.sleep(100);
}

All was working fine. Then I try to remove the sleep and then I notice that my animation was missing some images.

If my understanding is correct this is because the draw is actually asynchronous.

But how can I do a wait until draw is done from my Displayable object ?

I tried to add in my paint function:

this.display.waitForEvent();

But instead of synchronization I get the following exception:

Exception in thread “DISPLpmp” java.lang.RuntimeException: MicroUI:E=1
at java.lang.System.getStackTrace(Unknown Source)
at java.lang.Throwable.fillInStackTrace(Throwable.java:82)
at java.lang.Throwable.(Throwable.java:37)
at java.lang.Exception.(Exception.java:18)
at java.lang.RuntimeException.(RuntimeException.java:18)
at ej.microui.display.Display.waitForEvent(Display.java:392)
at com.mycompany.Main.paint(Main.java:152)
at ej.microui.display.Displayable.paintDisplayable(Displayable.java:199)
at ej.microui.display.Display.executeEventRepaint(Display.java:539)
at ej.microui.display.DisplayPump.execute(DisplayPump.java:193)
at com.is2t.microui.io.DisplayPumpKF.internalPump(DisplayPumpKF.java:94)
at ej.microui.display.DisplayPump.run(DisplayPump.java:97)
at java.lang.Thread.run(Thread.java:303)
at java.lang.Thread.runWrapper(Thread.java:454)

Can you help me please ?

Hi @jshaw,

If my understanding is correct this is because the draw is actually asynchronous.

Yes the repaint function is asynchronous, it will add few events in the pump.

But instead of synchronization I get the following exception MicroUI:E=1:
This error is :
Deadlock. Cannot wait for an event in the same thread that runs events.Display.waitForEvent() must not be called in the display pump thread (e.g. inpaint methods).

So if you really want to use the waitForEvent, you could use:

while (true) {
   main.repaint();
   this.display.waitForEvent();
   main.update();
   Thread.sleep(100);
}

But this thread should not be in the display pump.

Another way to do would be to trigger the update and repaint of the image from the render function (for instance with a wait and notify).

Yet another way would be to use an explicit flush to avoid all the display pump.

public static void main(String[] args) {
	Display display = Display.getDefaultDisplay();
	ExplicitFlush g = display.getNewExplicitFlush();

	int color = Colors.BLACK;
	int x = 0;
	int y = 0;
	int size = 100;

	while (true) {
		// Modify model.

		// Draw.
		g.setColor(color);
		g.fillRect(x, y, size, size);
		g.flush();
	}

}

Regards,

Thank you Pierre,

The ExplicitFlush was what I was looking for.

Concerning the first part of your response I’m not sure to understand it all.
Perhaps you can provide me a link to some documentation.

Thank you.

You can find the documentation for the error codes on the device developer guide.