Skip to main content

Canvas painting and the AWT Dispatch Thread

5 replies [Last post]
generessler
Offline
Joined: 2010-02-02
Points: 0

I'm confused. The code in the BufferStrategy API docs
http://docs.oracle.com/javase/6/docs/api/java/awt/image/BufferStrategy.html
shows a Window being created and an animation painted _not_ from the AWT dispatch thread.

I followed this pattern to implement my own animation in a Canvas. Canvas.paint() and Canvas.update() are overridden to do nothing. A separate thread repeatedly paints the BufferStrategy back buffer and then call BufferStrategy.show(). FWIW, the Canvas is in a Cardlayout and the thread only starts when the Canvas is selected.

It works great on a collection of test machines. But my app needs to be robust for 10's of thousands of machines, hardware unknown. Not much margin for error.

Now I find warnings in various places never to draw in anything but the AWT EDT.

So are the docs bogus? Or have I misread them? Or is continuous animation an exception to the EDT rule?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
anthony_p
Offline
Joined: 2006-07-24
Points: 0

Hi generessler,

AWT is a multi-threaded GUI toolkit, so as long as your app is AWT-based you may do whatever you want on any thread (unless specification states otherwise for particular methods).

Swing, on the contrary, is a single-threaded GUI toolkit. If your app uses Swing library, you have to perform almost all GUI-related operations on the EDT only. Even though you may try and use an AWT component embedded into a Swing frame from any thread, it is still highly recommended to perform everything GUI-related on the EDT nevertheless, since multi-threaded calls may interfere with the Swing machinery.

Hope this helps.

--

best regards,

Anthony

generessler
Offline
Joined: 2010-02-02
Points: 0

Thanks. Extremely helpful.

I'm sure you see this: this deeply cripples the BufferStrategy's purpose. You'd like to render into the "back buffer" without slowing down the EDT, using the paint() method only to do backBuffer.show(). This way there is graceful degradation in frame rate as render time increases. Even if rendering every frame takes a second, the GUI would be responsive and you'd see the once-per-second update. With rendering in the EDT, GUI responsiveness will get worse as render time increases.

Back to the future: I'm in 1991 writing to the Windows 3.1 API.

anthony_p
Offline
Joined: 2006-07-24
Points: 0

You're welcome.

I'm not exactly an expert in Swing, but I believe there are more effective ways to implement animation/continuous redrawing in a Swing app than using the BufferStrategy class (I may be wrong though). I suggest to search more info on the Internet (these very forums perhaps) regarding this toplic.

Also, Java FX is very suitable for performing such kind of drawing, and you can easily embed an FX scene into a Swing app using the JFXPanel widget. You might want to explore this possibility if you really need an effective way to render something continuously.

PS. Actually, Win16 API was pretty awesome. Unlike int 21h, for example. ;)

generessler
Offline
Joined: 2010-02-02
Points: 0

Thanks.

I rejiggered everything to use a SwingUtilities.Timer to call repaint() and then rendered with the BufferStrategy inside the Paint method. It lost about 5% of the previous performance, but it's completely Swing compatible now. The Swing Timer includes an option to dump events if the handler is too slow to keep up with repeated events, so I used that to deal with the case where the renderer can't keep up with the timer. On the slowest computer I can find, it's doing about 20 fps, so even though everything is in the EDT, it's fine.

I was referring to the crazy Win16 and MacOS "cooperative multitasking" model, wherin you got to implement something like your own thread scheduler in every program and one bad actor could bring down the whole system. Unfortunately I'm also old enough to have an MSDOS Interrupt list lying around somewhere. How about Terminate-And-Stay-Resident?

generessler
Offline
Joined: 2010-02-02
Points: 0

Thanks. Extremely helpful.