[kepler-dev] Found simple fix was Re: Splash screen and corresponding changes

Kevin Ruland kruland at ku.edu
Tue Feb 14 09:30:34 PST 2006


Christopher,

Actually very little is in the Swing event handler thread which keeps 
the ui responsive.

I'm looking at the Java tutorial  Threads and Swing page and see The 
Single-Thread Rule

*Rule:*  Once a Swing component has been realized, all code that might 
affect or depend on the state of that component should be executed in 
the event-dispatching thread.

So, the initial Component.setVisible(true) (or the deprecated equivalent 
Component.show()) can be executed outside the Event Handler thread, but 
from that point forward, it cannot be manipulated from outside the Swing 
event handler thread.

In the case of SplashScreen, the Timer's expire event is after the 
initial show and therefore should be in the event handler thread.  I'll 
put it in an invokeLater().

Kevin


Christopher Brooks wrote:
> Hi Kevin,
>
> I'm not so sure about this change, especially before I take off for
> parts unknown.
>
> We've used invokeLater() with great success.
>
> I'd like to understand why the change to a SwingWorker thread is
> necessary first, before making the change.
>
> Also, in KeplerMain, are you sure everything is in the Swing Event
> Thread?  In particular, will the SplashScreen and SplashScreen.Timeout
> be in the Swing Event Thread?  Maybe try calling
> SwingUtilities.isEventDispatchThread() and throwing an exception if
> it is not?
>
> I'm not sure if I have time to hack around with today and tomorrow, I
> have some other tasks.  I'd rather be doing this work, but other tasks
> call my name.
>
> Maybe the thing to do would be to check in a copy of VergilApplication
> in to the kepler exp directory for experimentation?  
>
> _Christopher
>
>
> --------
>
>     Christopher,
>     
>     After pulling things apart, looking at the thread allocation, the
>     putting everything back together, I found a very simple fix to the
>     problems I've been seeing.  Basically, in VergilApplicaiton.main()
>     instead of using SwingUtilities.invokeLater() to run
>     VergilApplication(args), use a SwingWorker thread.  I don't really
>     understand the subtle between these two different mechanisms (since
>     SwingWorker uses invokeLater), but indications are good that the splash
>     appears, is refreshed, and continues to receive mouse events even while
>     Kepler is doing all it's work.
>     
>     BTW - what I saw when I removed the invokeLater() from main and put
>     invokeLater in _createEmptyConfiguration was the EventThread stopping
>     and restarting quite frequently.  I think it was restarting whenever one
>     of the actors was constructed - perhaps to render icons or something.  I
>     don't really know.  Although that code change seemed to work too, I
>     didn't really like the frequent thread startup/shutdown.
>     
>     Here's the diff.
>     
>     $ diff -wc ../ptII/ptolemy/vergil/VergilApplication.java
>     src/exp/ptolemy/vergil/VergilApplication.java
>     *** ../ptII/ptolemy/vergil/VergilApplication.java       Mon Feb 13
>     08:57:11 2006
>     --- src/exp/ptolemy/vergil/VergilApplication.java       Tue Feb 14
>     09:39:49 2006
>     ***************
>     *** 34,41 ****
>       import java.util.LinkedList;
>       import java.util.List;
>      
>     - import javax.swing.SwingUtilities;
>     -
>       import ptolemy.actor.gui.Configuration;
>       import ptolemy.actor.gui.Effigy;
>       import ptolemy.actor.gui.JNLPUtilities;
>     --- 34,39 ----
>     ***************
>     *** 45,50 ****
>     --- 43,49 ----
>       import ptolemy.actor.gui.PtolemyPreferences;
>       import ptolemy.data.expr.Parameter;
>       import ptolemy.gui.GraphicalMessageHandler;
>     + import ptolemy.gui.SwingWorker;
>       import ptolemy.kernel.CompositeEntity;
>       import ptolemy.kernel.attributes.URIAttribute;
>       import ptolemy.kernel.util.ChangeRequest;
>     ***************
>     *** 139,161 ****
>               // weird things happens at the user interface level.  This
>               // seems to prevent occasional errors rending HTML under Web
>     Start.
>               try {
>     !             // NOTE: This is unfortunate... It would be nice
>     !             // if this could be run inside a PtolemyThread, since
>     !             // getting read access the workspace is much more efficient
>     !             // in PtolemyThread.
>     !             SwingUtilities.invokeLater(new Runnable() {
>     !                 public void run() {
>                           try {
>     !                         new VergilApplication(args);
>                           } catch (Throwable throwable) {
>                               System.err.println("xxxxxxxxxxxxxxxxxxxx");
>      
>                               // If we get an Error or and Exception while
>                               // configuring, we will end up here.
>                               _errorAndExit("Command failed", args, throwable);
>                           }
>                       }
>     !             });
>               } catch (Throwable throwable2) {
>                   // We are not likely to get here, but just to be safe
>                   // we try to print the error message and display it in a
>     --- 138,158 ----
>               // weird things happens at the user interface level.  This
>               // seems to prevent occasional errors rending HTML under Web
>     Start.
>               try {
>     !             SwingWorker w = new SwingWorker() {
>     !                 public Object construct() {
>                           try {
>     !                     return new VergilApplication(args);
>                           } catch (Throwable throwable) {
>                               System.err.println("xxxxxxxxxxxxxxxxxxxx");
>      
>                               // If we get an Error or and Exception while
>                               // configuring, we will end up here.
>                               _errorAndExit("Command failed", args, throwable);
>     +                         return null;
>                           }
>                       }
>     !             };
>     !             w.start();
>               } catch (Throwable throwable2) {
>                   // We are not likely to get here, but just to be safe
>                   // we try to print the error message and display it in a
>     
>     
>     
>     Kevin Ruland wrote:
>     > As a follow up, the second experiment of putting selected lines from
>     > _createEmptyConfiguration() into invokeLater() calls also helped out
>     > greatly.  I cannot inherit the VergilApplication and reimplement the
>     > _createEmptyConfiguration( ) method because of some critical private
>     > data members (configuration for one).
>     >
>     > After a few more hours of hacking we'll probably end up with all the
>     > splash functionality in VergilApplication itself.  This does have at
>     > least one added benefit because VergilApplication will know exactly
>     > when to bring the splash down so there will be no need for a timer.  I
>     > don't feel completely comfortable with the work I'm doing now because
>     > I don't really understand the deeper Ptolemy/Vergil issues and don't
>     > have access to all the test cases.  Christopher, if you can, I'd like
>     > to leave this in your court to finish.
>     >
>     > Kevin
>     >> The first experiment (removing the invokeLater from main()) was
>     >> promising.  Now to coerce
>     >> VergilApplication._createEmptyConfiguration() to use invokeLater().
>     >>   
>     >
> --------
>   



More information about the Kepler-dev mailing list