Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / GUI / October 2004

Tip: Looking for answers? Try searching our database.

Some SwingUtilities.invokeLater Myth

Thread view: 
sytee - 21 Oct 2004 15:52 GMT
after reading http://java.sun.com/docs/books/tutorial/uiswing/mini/threads.html,
i have some doubt:

consider:

====== this code is running in another worker Thread ======

       //  SwingUtilities makes sure code is executed in the event
thread.
       SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                  progressBar.setValue(50);
              }           
       });

===============================================

SwingUtilities.invokeLater is to ensure any GUI update code to be
performed in the event dispath thread.

1. Why we to explicitly put the progressBar.setValue(50) inside the
SwingUtilities.invokeLater? i thought the call itself to
progressBar.setValue(50) ALONE inside a user thread, will "Schedule A
Task To Event-Dispath Thread To Update The Progress Bar".

2. Inside the user thread, we have to explicitly put every single GUI
update code to the SwingUtilities.invokeLater. isn't that is a bit
cumbersome? imagine we have thoundsand of line of GUI update code in a
single thread, then we have to make thousand call to the
SwingUtilities.invokeLater.

consider:

==== this code is running in another thread===

        // long processing........ blah blah blah

       SwingUtilities.invokeLater(new Runnable() {
              public void run() {                            
                  progressBar.setValue(1);
              }           
       });
       
       // another long processing........ blah blah blah

       SwingUtilities.invokeLater(new Runnable() {
              public void run() {                            
                  progressBar.setValue(2);
              }           
       });

       // another another long long processing...... blah blah blah
       SwingUtilities.invokeLater(new Runnable() {
              public void run() {                            
                  progressBar.setValue(3);
              }           
       });

===============================================

thank you.

regards
yan cheng
xarax - 21 Oct 2004 18:22 GMT
> after reading http://java.sun.com/docs/books/tutorial/uiswing/mini/threads.html,
> i have some doubt:
[quoted text clipped - 6 lines]
> thread.
>         SwingUtilities.invokeLater(new Runnable() {

This is creating a new instance of an anonymous class
that implements Runnable.

>                public void run() {
>                    progressBar.setValue(50);
>                }

This is the run() method that will be called
LATER when the Runnable instance is removed
from the event dispatch queue.

>         });
>
[quoted text clipped - 7 lines]
> progressBar.setValue(50) ALONE inside a user thread, will "Schedule A
> Task To Event-Dispath Thread To Update The Progress Bar".

The call to setValue() is NOT in invokeLater. The call
happens later when the Runnable object is executed in
the event dispatched thread.

> 2. Inside the user thread, we have to explicitly put every single GUI
> update code to the SwingUtilities.invokeLater. isn't that is a bit
> cumbersome? imagine we have thoundsand of line of GUI update code in a
> single thread, then we have to make thousand call to the
> SwingUtilities.invokeLater.

No. Some Swing methods can be invoked safely from
another thread, but you MUST READ THE DOCUMENTATION
to determine which methods are thread-safe. Most
Swing methods are not thread-safe.

Also, you can put as much code as you want into the
run() method of your Runnable instance that you pass
to invokeLater(). You DO NOT have to isolate each
Swing method to a separate Runnable and separate
call to invokeLater().

> consider:
>
[quoted text clipped - 24 lines]
>
> ===============================================

Yes, that's how it works. Nothing wrong with it. Each
time the user thread needs to update the GUI, a Runnable
instance is placed on the AWT Event Dispatch queue by
calling invokeLater(). The user thread then continues
on its merry way and the GUI will eventually get updated
as the JVM gets around to dispatching the AWT Event
Dispatch Thread. Works fine for me.

So, what's the Myth?
Filip Larsen - 21 Oct 2004 18:40 GMT
> 2. Inside the user thread, we have to explicitly put every single GUI
> update code to the SwingUtilities.invokeLater. isn't that is a bit
> cumbersome? imagine we have thoundsand of line of GUI update code in a
> single thread, then we have to make thousand call to the
> SwingUtilities.invokeLater.

There is nothing that prevents you from bundling updates together and do
them in one go instead of a thousand. If you have, say, 100 updates per
second then it makes good sense to bundle (and perhaps even coalesce)
the updates so you only need one or two calls to invokeLater per second.

However, if you really need to update thousands of different GUI
components from your worker threads I would say you need to rethink your
application design; a worker thread should not have such intimate
knowledge of the GUI.

Regards,
Signature

Filip Larsen

xarax - 21 Oct 2004 20:12 GMT
> > 2. Inside the user thread, we have to explicitly put every single GUI
> > update code to the SwingUtilities.invokeLater. isn't that is a bit
[quoted text clipped - 11 lines]
> application design; a worker thread should not have such intimate
> knowledge of the GUI.

Ideally, the worker thread should use invokeLater() to
execute a controller component, which itself understands
what GUI components to update.
hiwa - 22 Oct 2004 02:21 GMT
I feel the OP means that he just want to write simply:

progressBar.setValue(50);

In his user code. Then, the Java runtime should take care of all the
details including invokeLater(), Runnable, run() etc., etc.

In other words, his claim seems to be that application programmer
should not wirte parts of implementation details of an API.
Steve W. Jackson - 25 Oct 2004 16:51 GMT
>:I feel the OP means that he just want to write simply:
>:
[quoted text clipped - 5 lines]
>:In other words, his claim seems to be that application programmer
>:should not wirte parts of implementation details of an API.

There's NO NEED to put any of the calls to setValue() in an
invokeLater() call.  The ProgressBar carries a BoundedRangeModel and a
ChangeListener.  When any of the bounded values change, notification is
given by way of that listener.  That notification occurs on the Event
Dispatch Thread.

= Steve =
Signature

Steve W. Jackson
Montgomery, Alabama

Babu Kalakrishnan - 25 Oct 2004 18:00 GMT
>>:I feel the OP means that he just want to write simply:
>>:
[quoted text clipped - 11 lines]
> given by way of that listener.  That notification occurs on the Event
> Dispatch Thread.

Which version of the JDK are you referring to ? As far as I can recall,
a setValue call on a JProgressBar needed to be done from the EDT at
least till JDK 1.4. Don't remember seeing any code in the source of the
DefaultBoundedRangeModel class or its API docs that indicates that the
notification is done in the EDT. (I think the notification is performed
in the same thread that the change intimation is received - very similar
to the implementation of the models in other Swing components)

If the basis of your statement in the examples in the Java Tutorial
(where there is no invokeLater wrapper), you need to remember that the
examples use a javax.swing.Timer instance to set the values. A Timer
always fires in the EDT, and hence the wrapper is not required.

BK
Steve W. Jackson - 26 Oct 2004 16:16 GMT
>:Steve W. Jackson wrote:
>:> In article <6869384d.0410211721.6795310b@posting.google.com>,
[quoted text clipped - 30 lines]
>:
>:BK

I am in fact looking at 1.4.2 source with my installed JDK, but the
notifications there are done by way of a ChangeListener.  Unless I'm
mistaken (and it wouldn't be the first time), the events from these are
on the EDT just as those of an ActionListener.

= Steve =
Signature

Steve W. Jackson
Montgomery, Alabama

Babu Kalakrishnan - 26 Oct 2004 16:25 GMT
>>:Steve W. Jackson wrote:
>>:>
[quoted text clipped - 16 lines]
> mistaken (and it wouldn't be the first time), the events from these are
> on the EDT just as those of an ActionListener.

Yes - notifications _are_ done through a ChangeListener. But that does
not mean that it is done in the EDT. If you read the source carefully,
you'll notice that the stateChanged methods of the listeners are called
directly - in the same thread that setValue was called. (Just look at
the code flow starting at the setValue method).

BK
xarax - 25 Oct 2004 20:54 GMT
> >:I feel the OP means that he just want to write simply:
> >:
[quoted text clipped - 11 lines]
> given by way of that listener.  That notification occurs on the Event
> Dispatch Thread.

That is clearly wrong. Show/point us to the source
code where the change listener posts an event to
the EDT (or is the change listener somehow dispatched
on the EDT via the setValue()?).
Steve W. Jackson - 26 Oct 2004 16:42 GMT
>:> In article <6869384d.0410211721.6795310b@posting.google.com>,
>:>  HGA03630@nifty.ne.jp (hiwa) wrote:
[quoted text clipped - 19 lines]
>:the EDT (or is the change listener somehow dispatched
>:on the EDT via the setValue()?).

Doesn't a ChangeListener have its events fired on the EDT?  If not, then
I'm mistaken.  But the BoundedRangeModel fires its change listener when
any of the bounded properties changes.  And calling setValue results in
firing the BRM's change listener.

= Steve =
Signature

Steve W. Jackson
Montgomery, Alabama

xarax - 26 Oct 2004 17:04 GMT
> >:> In article <6869384d.0410211721.6795310b@posting.google.com>,
> >:>  HGA03630@nifty.ne.jp (hiwa) wrote:
[quoted text clipped - 24 lines]
> any of the bounded properties changes.  And calling setValue results in
> firing the BRM's change listener.

Calling setValue() eventually flows to calling the change listener,
but all of this happens on the thread that called setValue(). There
is no magic in the fireStateChanged() method that will cause the
change listener to get called on the EDT. The listener is called
directly by the same thread that called setValue().


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.