Jacob said:
I have a processing loop that in each iteration
update an image in GUI. When I run the program
only the last GUI refresh is actually visible.
I guess the entire processing is complete before
the AWT thread is ever dispatched and then all
the events are collapsed into one.
How can I force the GUI refresh to actually execute
in each iteration? (I tried the paintImmediately(),
buth I don't like it and it didn't work either).
Alternatively how should I organize a threaded
solution?
I think you have two problems - not one. The first is about repaint events
getting collapsed into one . Yes, the swing subsystem does optimize painting by
combining several repaint calls into one, and I think paintimmediately should be
able to take care of that for you (provided you allow the Event Dispatch Thread
to run).
The second problem occurs if you're working with images (as you seem to be).
Even if the EDT does run your painting code, the drawImage method doesn't block,
but instead spawns a separate thread to perform the image loading/preparation.
It does the actual painting by using the default ImageObserver implementation of
java.awt.Component which simply queues a new repaint() call as and when more
pixels are available for painting. Now if you have changed the image before this
occurs, it would throw away the image that is currently loading and initiate
another image preparation cycle with the new image - and it is even possible
that the actual painting might never take place if you are switching the image
source too rapidly. This is probably the reason why paintImmediately isn't
working for you.
If you want to ensure that the changes are seen on screen, you would have to
pace your processing loop appropriately to ensure that you don't change the
image source before the actual painting of the image has taken place. Also you
might need to implement a custom ImageObserver implementation that forces an
immediate paint rather than queueing a repaint() request. (And needless to say,
you have to do your processing outside the EDT, and call paintImmediately in the
EDT using the invokeLater hook)
BK