[...]
That's not what I am talking about. Whether you're talking Swing or
EDT, you need to make sure you are making calls to the component on
the EDT.
I agree. The Observer's update() method should defer drawing,
It does, by virtue of the repaint() method deferring actual drawing.
but it can
get interim results and update component data models, e.g. a
BufferedImage or a TableModel. It then calls repaint() to schedule the
screen update on the EDT.
But those "component data models" need to be synchronized. If you are not
executing your code on the EDT, then they may be being used by code
running on the EDT at the same time you are modifying them. And that's on
top of the fact that Swing does not automatically handle cross-thread
updates to data models for GUI components.
For example (from
http://java.sun.com/javase/6/docs/api/javax/swing/package-summary.html#threadi
ng):
...if a TableModel is attached to a JTable, the TableModel
should only be modified on the event dispatching thread.
If you modify the model on a separate thread you run the
risk of exceptions and possible display corruption
Conversely, if you _are_ executing your code on the EDT, then the data
model from which you're getting your actual information (that is, the
processing thread's model data structure) is what needs to be synchronized.
The bottom line is that you have a processing thread that's generating
data, but you can only display data on the EDT, which is by definition
going to be a different thread from the processing thread. You _must_
address synchronization of those threads any time you want data to flow
from one thread to the other. And the only way to present the results of
the processing (interim results or otherwise) to the user is to have data
flow from one thread to the other.
On top of all this, the Observable class doesn't give us any assurance
that Observer implementers are going to be called on the same thread on
which Observable.notifyObservers() is called. So your Observer
implementer cannot make the assumption that it's update() method is called
on the EDT, even if you call notifyObservers() on the EDT.
And finally (to conclude this particular logical progression), since your
Observer implementation cannot make the assumption that its update()
method is called on the EDT, it must itself explicitly ensure that any
interaction it has with Swing is done on the EDT, except possibly for
things that are explicitly documented as not needing that (in this case,
that would be the repaint() method, but not any of the other things you
might do in order to update the GUI).