How to force GUI updates?

J

Jacob

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?

Thanks!
 
P

Paul Lutus

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?

You must put the processing loop in a separate thread.
 
B

Babu Kalakrishnan

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
 
J

Jacob

Babu said:
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)

Thanks, Babu.

I am pretty sure this explains the observed behaviour,
and I should be able to get around it based on your info.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,430
Messages
2,571,676
Members
48,796
Latest member
Greg L.

Latest Threads

Top