Force draw between mouse/keyboard events

Hello,
In my sketch, I do some quite heavy computations on keyboard or mouse events. These computations can take 1s or so to be processed.

If I type on the keyboard while the last computation has not ended, immediately after the end it starts again to process the new event.

Between these two events, I want to force the screen to be completely refreshed, as it’s done with an iteration of draw().
I tried several things, as calling draw(), redraw() and the end of keyPressed() function but the screen is not refreshed.

Do someone have an idea ?

Thanks

Have you tried calling draw() from your event handlers? Computations that take a second are indeed heavy, so heavy that there should be ways to make them faster.

Hello,
Yes, of course. But the screen is not updated.

You have discovered the the hard way that event handler code should be as fast as practicable if you don’t want your screen to hang. To understand why you need to understand how event driven programming works.

In Java event handling code runs on a special thread known as the event dispatch thread (EDT). This thread is also responsible for drawing the display.

Now image you press a key or mouse button this generates an event which is put on the event queue (EQ). At some point the EDT will take the event off the front of the queue and process its event handler (your code) on the EDT. While your code is executing any new event is added to the EQ to be processed when its turn arrives. At the same time draw requests (~60 times per second) are also added to the EQ and wait their turn to be processed. Since many key and mouse events can be generated between draw events then you can see the problem.

The solution is to ensure that the event handler execution time is as fast as possible. One way to do this is to do the heavy calculations on a separate thread but this is not a trivial exercise to get it right.

If you decide to go the route of using separate thread for your heavy duty code there are somethings to be aware of

  1. Avoid all graphics commands inside the heavy-duty code
  2. The heavy duty code and your main code should not access the same variables at the same time

Point 2 is important for example if your heavy duty code updates an array that is used in your draw method it will lead to concurrent access exceptions if both threads try to access the array at the same time.

The solution here is for the thread to have its own variables and when complete use a semaphore (a boolean variable works well) to signal it is finished and your main thread can safely copy the data into its own variables.

Although using a separate thread is probably the best solution there is another approach and that involves breaking down the heavy duty code into smaller chunks which can be executed in turn to produce the final data. The event handler does not execute these chunks rather it signals the EDT that it should start executing the chunks in turn, perhaps one chunk per frame.

Hope this helps get you started on a solution.

3 Likes

Thank you a lot for your very good explanation.
I understand why it’s not working.

Easier than the thread, I will juste write a flag with the key which was pressed. I will then place my heavy calculations in the draw() and compute it when the flag is raised : it will solve my problem, I think.