M
mkrause
Having built several Java swing applications in the past, I am well
aware of the potential for problems if you update a Swing component on
a thread other than the AWT thread. Knowing this, I have been careful
to use Runnable + SwingUtilities.invokeLater (or
SwingUtilities.invokeAndWait) where it's needed, or I'll use the
SwingWorker class to perform a bunch of non-GUI related work in the
construct and then udpate my GUI components in the finished method.
I think an assumption I have been making, however, has gotten me into
trouble. Let me try to illustrate the problem:
If you have a model object I'll call M which is created on a server and
then passed to the client via Java RMI. Once on the client, M can be
accessed from a variety of different threads. Now assume that some GUI
component such as a JList indirectly gets notified when something in M
changes. (I say indirectly because the class that actually receives
the property change from M is the ListModel that in turn notifies the
JList through a ListModel event.)
Now let's say that this property of interest changes, so M fires the
property change from a thread other than the AWT thread. The
PropertyChangeSupport inside of this model class will fire the change
by walking through its listener list and making method calls to all
objects that were interested in the change. As mentioned before, one
of the things that cares about this property change is a ListModel.
The ListModel will receive this property change on the same thread and
then fire off a different event that will be received by a JList
component - again on the SAME thread - and... voila... we have a GUI
component being updated by a thread other than the AWT thread. Not
good.
So, the issue really is to not assume DefaultListModel or
DefaultTableModel, etc., will make sure to fire their changes on the
AWT thread, because they won't. There is no special code in these
classes to ensure that this is done. The onus to do so falls on the
application developer.
Has anyone else come to this realization, and if so, how did you deal
with this problem? I have searched for other posts related to this
problem but haven't found much.
- Mike
aware of the potential for problems if you update a Swing component on
a thread other than the AWT thread. Knowing this, I have been careful
to use Runnable + SwingUtilities.invokeLater (or
SwingUtilities.invokeAndWait) where it's needed, or I'll use the
SwingWorker class to perform a bunch of non-GUI related work in the
construct and then udpate my GUI components in the finished method.
I think an assumption I have been making, however, has gotten me into
trouble. Let me try to illustrate the problem:
If you have a model object I'll call M which is created on a server and
then passed to the client via Java RMI. Once on the client, M can be
accessed from a variety of different threads. Now assume that some GUI
component such as a JList indirectly gets notified when something in M
changes. (I say indirectly because the class that actually receives
the property change from M is the ListModel that in turn notifies the
JList through a ListModel event.)
Now let's say that this property of interest changes, so M fires the
property change from a thread other than the AWT thread. The
PropertyChangeSupport inside of this model class will fire the change
by walking through its listener list and making method calls to all
objects that were interested in the change. As mentioned before, one
of the things that cares about this property change is a ListModel.
The ListModel will receive this property change on the same thread and
then fire off a different event that will be received by a JList
component - again on the SAME thread - and... voila... we have a GUI
component being updated by a thread other than the AWT thread. Not
good.
So, the issue really is to not assume DefaultListModel or
DefaultTableModel, etc., will make sure to fire their changes on the
AWT thread, because they won't. There is no special code in these
classes to ensure that this is done. The onus to do so falls on the
application developer.
Has anyone else come to this realization, and if so, how did you deal
with this problem? I have searched for other posts related to this
problem but haven't found much.
- Mike