As Paul Webster likes to say, “I want to tell you a story.” Unlike Paul’s, my story has nothing to do with commands, key bindings, or Ketchup. Mine is about the splash screen.
No, wait. Come back! I promise it’s at least kind of interesting!
Over the past few milestones the SWT and runtime teams have been working on a way to get the splash screen re-implemented in SWT. There are all kinds of reasons why this is hard to do but in the end they got it done and in a most creative way at that. The basic gist of it is that the java process starts the Eclipse framework which uses native code to bring up a window. The window handle of this shell is published as a system property and later (once some heavy lifting has been done by the framework) the workbench takes that handle and wraps it in an SWT shell. We then Do Horrible Things To It such as smear it with progress bars, progress messages, and build ids.
Now for the exciting part - you too can do Horrible Things to the splash!
As of I20070130 there is a new extension point in org.eclipse.ui -
. Splash handler is like Intro in that there can only be one intro implementation per product. The extension point is quite simple. There are two possible elements -
and
. The first describes a splash handler while the later binds a given splash handler to a product. For example:
<extension point="org.eclipse.ui.splashHandler"> <splashHandler class="com.xyz.splash.Handler" id="com.xyz.splash"> </splashHandler> <splashHandlerProductBinding productId="com.xyz.product" splashId="com.xyz.splash"> </splashHandlerProductBinding></extension>
Nothing special, nothing complicated. The only interesting part is the class attribute of the
element. The value of this attribute must point to a class that extends
. This class has three interesting methods that you can override:
/** * Initialize this splash implementation. This is called very early in the * workbench lifecycle before any window is created. The provided shell will * already have a background image provided to it but subclasses are free to * customize the shell in whatever way they see fit. Subclasses should * ensure that they call the base implementation of this method at some * point after their own method is invoked. * * Calls to this method will be made from the UI thread * * @param splash * the splash shell */ public void init(Shell splash); /** * Signal the handler to end the splash and dispose of any resources. * Subclasses should ensure that they call the base implementation of this * method at some point after their own method is invoked. * * Calls to this method will be made from the UI thread. */ public void dispose(); /** * Return the progress monitor responsible for showing bundle loading. * Default implementation returns a null progress monitor. * * Calls made to methods on this progress monitor may be made from non-UI * threads so implementors must take care to ensure proper synchronization * with the UI thread if necessary. * * @return the progress monitor * @see NullProgressMonitor */ public IProgressMonitor getBundleProgressMonitor();
The first,
, is where you can add custom controls to your splash screen. For instance, you can add progress bars, animation, icons, or even custom controls. Additionally, you could have a splash that contains user name and password fields. This splash implementation would block until a user enters something in both boxes.
The second method,
, can be used to perform custom cleanup. This method will be invoked sometime after the workbench has finished initializing itself. In addition to cleanup, this method could be used to block closure of the splash until some condition has been satisfied. For instance, you could have a splash screen that didn’t return from this method until the user hit the space bar.
The final method,
is where you can hook progress controls created in the init method to a progress monitor. This monitor will be called by the workbench when plug-ins are loaded.
The story continues tomorrow (provided anyone is still awake).







7 responses so far ↓
1 Alex // Jan 29, 2007 at 9:47 pm
Ohhh, I so want 3.3 release yesterday.
2 Benny // Jan 30, 2007 at 5:13 am
Yay, really good news Kim!
3 AlBlue // Jan 30, 2007 at 8:44 am
Lookin’ good
4 Sebastien // May 30, 2007 at 4:31 am
This doesn’t seems to work with the latest 3.3 (tested with M7 and RC2). Any time you synchronize your product, the plugin.xml lose the splashHandlerProductBinding element. Any idea ?
5 pookzilla // May 30, 2007 at 8:03 am
Sebastian: You should probably log a bug against PDE for this ASAP.
6 Sebastien // May 30, 2007 at 10:27 am
Thanks for your answer, and that’s what i did (bug n° 189950). I managed to make it work, it seems that the class name must be InteractiveSplashHandler on M7 and RC2, if not the synchronize or launch product remove the splashHandlerProductBinding tag so we just renamed our splash class to make it work. (tested on a fresh install / workspace of course
)
7 Amos // Aug 31, 2008 at 10:23 pm
For those too lazy to check the bug mentioned by Sebastien, a comment there states that the “solution for all your problems is just use a different splash ID for the splash handler elements. Say ‘org.test.rcp.splashHandlers.intergalactic’.
This will effectively ‘orphan’ the binding from the template mechanism and make it your own and consequently the synchronization operation will leave everything intact.” (from https://bugs.eclipse.org/bugs/show_bug.cgi?id=189950)
That workaround has worked for me - the issue is still not fixed in Ganymede…
Leave a Comment