initramfs
initramfs

Reputation: 8415

The Necessity of dispatching simple events with the EDT

Before I go on discussing the basic query I would first like to state that I am fully aware of my question being against the standards of the AWT/Swing framework. My query is meant merely as a academic experience and should (hopefully) never be applied to real world applications.

The AWT/Swing framework is built upon a event based model which uses a single thread to dispatch events. All AWT/Swing related events events must be processed on the Event Dispatcher Thread (EDT) and any custom events that the programmer has programmed must be queued through the functions invokeAndWait() and invokeLater(). While this model ensures that the framework never suffers from any sort of thread concurrency issues it gives a big pain to programmers trying to write code around it (search swing issues on stackoverflow... quite a handful).

However... Years ago, before I got more familiar with the AWT/Swing model and the EDT I used to write code that violates many many java standards (code that'll make any reasonable programmer recoil in horror). One of these standards I violated was calling methods that updated the GUI through a thread thats not the EDT. To be precise it was a standard "long" task that resided on a secondary thread which periodically updated a JLabel with the current progress. Reviewing the code now I realized that despite the fact that the code directly violated the standard, it worked 100% of the time. I noticed no flickering, no corruption of text (since it was a JLabel), no random exceptions being thrown and no abnormal GUI behavior. Of course I know from one tiny example, one cannot simply determine the AWT/Swing standards are over-protective or unnecessary. And with this, my query lies:

For simple tasks like updating a JLabel (not even at a constant rate, maybe once or twice a second) is it truly necessary to perform it through the EDT? And what are the possible implications (apart from being despised by the whole java programming community) of this (I want a list of solid implications, not just "it might cause the EDT to mess up")?

Assume a model where only one thread updates the GUI (which is not the EDT) and the updates are infrequent and only update in atomic operations (updating strings, primitive data, etc) is it possible that the program can run free of problems caused by the EDT (I guess this counts as a hack?).

As a challenge, I was wondering if its possible anyone can come up with code that demonstrates a violation of the AWT/Swing model by dispatching events from another thread causing obvious and constant (as in I don't have to wait 2 hours for the GUI to flicker for 1 frame) problems?

And by the way, this might be unrelated but does a new EDT thread spawn for a new JFrame/Window object or do all of them run off the same thread? I can't imagine a resource-heavy multi-window system all running off one thread.

NB: I have never seen nor analyzed the source code of the AWT/Swing framework and all my knowledge is based on internet research and personal experience. If there is any mistake above, please feel free to correct me. For those programmers still in shock from my example above, I have updated all my projects to comply to the standard (what a pain).

Upvotes: 0

Views: 161

Answers (1)

Russell Zahniser
Russell Zahniser

Reputation: 16364

An example of where this fails: Set your JLabel to be right-aligned. Then drawing requires two steps - measuring the text, in order to calculate the position, and then drawing it. If you change the text while it is painting (say, due to an animation loop) the text will seem to jump occasionally.

In answer to your other question - there is only one EDT, for all GUI components.

Example of "constant and obvious" change: Suppose the JLabel has HTML content. In your background thread, after the text is set and a repaint is fired, a PropertyChange is also fired, which causes the UI delegate to reparse the HTML and set it in a client property (working in the background thread, although the UI assumes it is in the EDT because it is receiving an event).

So now you have a race condition: If the UI repaints the label (in the EDT) before it finishes calculating the HTML view in the background thread, it will paint the old HTML and your label will appear to not update.

You could say, "Well then, I just won't use HTML in my label." But the point is that situations like this are pervasive in the Swing libraries - a strong assumption is made everywhere that events are passed only on the EDT, and without reading a huge amount of the Swing source you can't guarantee that you won't run into a problem like this.

Upvotes: 3

Related Questions