Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse 4 » Splash Screen with Progress Bar and Messages
Splash Screen with Progress Bar and Messages [message #843741] Fri, 13 April 2012 06:21 Go to next message
Christoph Keimel is currently offline Christoph Keimel
Messages: 347
Registered: December 2010
Location: Germany
Senior Member
Hello

I would like to have a Splash Screen with Progress Bar and loading Messages in my pure e4 Application. The splash.bmp is displayed as documented.

To get the progress bar and the messages I tried to things:

1) I actived "Add a progress bar" and "Add a progress message" in the "Splash" tab of the product configuration. This has no effect in itself (except for the new properties in plugin.xml). Is there an API I can use to get the progress bar and the message area for further configuration?

2) I tried to use one of the templates. This creates an extension in the plugin.xml which points to a new class derived from AbstractSplashHandler. Since the AbstractSplashHandler is part of org.eclipse.ui.workspace I don't have this class available. It is a simple task to extract this class, but even then I get a compile error: "Unknown extension point: 'org.eclipse.ui.splashHandlers'. I conclude that this approach will only work by pulling in the compat-layer.

Is there another possible solution?

Greetings
Christoph
Re: Splash Screen with Progress Bar and Messages [message #843758 is a reply to message #843741] Fri, 13 April 2012 06:36 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5296
Registered: July 2009
Senior Member
Well my take would be to install a lifecycle handler and create a Shell.
This is no different to what happens in 3.x under the covers.

Maybe we should add another option in the plugin.xml where one can point
to a Splash-Bean and in future provide baseclasses people can derive from.

Tom

Am 13.04.12 12:21, schrieb Christoph Keimel:
> Hello
>
> I would like to have a Splash Screen with Progress Bar and loading
> Messages in my pure e4 Application. The splash.bmp is displayed as
> documented.
> To get the progress bar and the messages I tried to things:
>
> 1) I actived "Add a progress bar" and "Add a progress message" in the
> "Splash" tab of the product configuration. This has no effect in itself
> (except for the new properties in plugin.xml). Is there an API I can use
> to get the progress bar and the message area for further configuration?
>
> 2) I tried to use one of the templates. This creates an extension in the
> plugin.xml which points to a new class derived from
> AbstractSplashHandler. Since the AbstractSplashHandler is part of
> org.eclipse.ui.workspace I don't have this class available. It is a
> simple task to extract this class, but even then I get a compile error:
> "Unknown extension point: 'org.eclipse.ui.splashHandlers'. I conclude
> that this approach will only work by pulling in the compat-layer.
>
> Is there another possible solution?
>
> Greetings
> Christoph
Re: Splash Screen with Progress Bar and Messages [message #845779 is a reply to message #843758] Sun, 15 April 2012 08:18 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph Keimel
Messages: 347
Registered: December 2010
Location: Germany
Senior Member
Thanks for the tipp to get started @Tom.

I implemented an ISplashService as an OSGi service making it available to all parts in creation. This works very nicely. The question I am now facing is when to hide the splash screen.

My current solution is to subscribe to UIEvents.UILifeCycle.ACTIVATE, but I have the feeling that this is not guaranteed to be the last event that ends the building of the application or even to be fired during the startup. I thought about overriding the IAppicationContext to catch the call to applicationRunning() by the framework, but that seems like bad hack.

Imho it would be good, to have an event for the end of the application startup. Either as an UIEvent or as an annotation for the lifecycle handler. What do you think? Should I file a feature request for this or have I overlooked something?

Greetings
Christoph
Re: Splash Screen with Progress Bar and Messages [message #845802 is a reply to message #845779] Sun, 15 April 2012 08:36 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5296
Registered: July 2009
Senior Member
Hi,

Yes please file a bug for a specific framework event that ends the
startup process.

Tom

Am 15.04.12 14:18, schrieb Christoph Keimel:
> Thanks for the tipp to get started @Tom.
> I implemented an ISplashService as an OSGi service making it available
> to all parts in creation. This works very nicely. The question I am now
> facing is when to hide the splash screen.
>
> My current solution is to subscribe to UIEvents.UILifeCycle.ACTIVATE,
> but I have the feeling that this is not guaranteed to be the last event
> that ends the building of the application or even to be fired during the
> startup. I thought about overriding the IAppicationContext to catch the
> call to applicationRunning() by the framework, but that seems like bad
> hack.
> Imho it would be good, to have an event for the end of the application
> startup. Either as an UIEvent or as an annotation for the lifecycle
> handler. What do you think? Should I file a feature request for this or
> have I overlooked something?
>
> Greetings
> Christoph
Re: Splash Screen with Progress Bar and Messages [message #845810 is a reply to message #845802] Sun, 15 April 2012 08:45 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph Keimel
Messages: 347
Registered: December 2010
Location: Germany
Senior Member
Bug 376821
Re: Splash Screen with Progress Bar and Messages [message #857153 is a reply to message #843741] Thu, 26 April 2012 05:35 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph Keimel
Messages: 347
Registered: December 2010
Location: Germany
Senior Member
I have been asked to share my solution, so here it is. There is still work to be done though ... i.e. I haven't included a progress bar yet.

1) Interface of the Service
public interface ISplashService {
	/**
	 * Tell the Service where to find the Splash-Image
	 * @param pluginId ID of teh Plugin where the Image resides
	 */
	public void setSplashPluginId(String pluginId);
	
	/**
	 * Tell the service the path and name of the Splash-Image
	 * @param path Path and filename of the Spalsh-Image
	 */
	public void setSplashImagePath(String path);
	
	/**
	 * Open the Splash-Screen
	 */
	public void open();
	
	/**
	 * Colse the Splash Screen
	 */
	public void close();
	
	/**
	 * Set the displayed message on the Splash-Screen
	 * @param message Text-Message to be displayed.
	 */
	public void setMessage(String message);
}


2) Register the Service with OSGi (as declarativ service):
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"  name="de.emsw.ui.splash">
   <implementation class="de.emsw.ui.splash.internal.SplashServiceImpl"/>
   <service>
      <provide interface="de.emsw.ui.splash.ISplashService"/>
   </service>
</scr:component>


3) Using the Service in the LifeCycleManager
@PostContextCreate
void postContextCreate(final ISplashService splashService, final IEventBroker eventBroker) {
	splashService.setSplashPluginId(YOUR_PLUGIN_ID);
	splashService.setSplashImagePath(YOUR_PLUGIN_PATH);
	splashService.open();
	splashService.setMessage("Starting Applikation ...");
	
	// The should be a better way to close the Splash
	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=376821
	eventBroker.subscribe(UIEvents.UILifeCycle.ACTIVATE, new EventHandler() {
		@Override
		public void handleEvent(Event event) {
			splashService.close();
			eventBroker.unsubscribe(this);
		}
	});
}


4) Updating the Message (by Example)
public class SomePart {
	@PostConstruct
	void postConstruct(ISplashService splashService) {
		splash.setMessage("Loading Something ...");
	}
	
	...
}


5) The Service Implementation
public class SplashServiceImpl implements ISplashService {
	private String pluginId = null;
	private String splashPath = "splash.bmp";
	private Shell splashShell = null;
	private Label textLabel = null;
	private String nextMessage = null;
	
	@Override
	public void setSplashPluginId(String pluginId) {
		Assert.isLegal(pluginId != null && !pluginId.equals(""));
		this.pluginId = pluginId;
	}

	@Override
	public void setSplashImagePath(String splashPath) {
		Assert.isLegal(splashPath != null && !splashPath.equals(""));
		this.splashPath = splashPath;
	}
	
	@Override
	public void open() {
		if (pluginId == null)
			throw new IllegalStateException("The SplashPluginId has not been set.");
		if (splashPath == null)
			throw new IllegalStateException("The SplashImagePath has not been set.");
		
		logger.info("Showing Splash Screen ...");
		splashShell = createSplashShell();
		splashShell.open();
	}
	
	private Shell createSplashShell() {
		final Shell shell = new Shell(SWT.TOOL | SWT.NO_TRIM);
		Image image = createBackgroundImage(shell);
		shell.setBackgroundImage(image);
		shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
		
		final GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		layout.marginHeight = 40;
		layout.marginWidth = 20;
		layout.verticalSpacing = 6;
		layout.horizontalSpacing = 6;
		shell.setLayout(layout);
		
		// TODO Set the postion and stlye of the text from outside to make the service reusable
		textLabel = createTextLabel(shell);
		
		Rectangle imageBounds = image.getBounds();
		shell.setSize(imageBounds.width, imageBounds.height);
		shell.setLocation(getMonitorCenter(shell));
		return shell;
	}

	private Image createBackgroundImage(Shell parent) {
		final Image splashImage = getImageDescriptor(pluginId, splashPath).createImage();
		parent.addDisposeListener(new DisposeListener() {
			@Override
			public void widgetDisposed(DisposeEvent e) {
				splashImage.dispose();
			}
		});
		return splashImage;
	}
	
	private ImageDescriptor getImageDescriptor(String pluginId, String path) {
		try {
			if (!path.startsWith("/")) {
				path = "/" + path;
			}
			URL url = new URL("platform:/plugin/" + pluginId + path);
			url = FileLocator.resolve(url);
			return ImageDescriptor.createFromURL(url);
		} catch (MalformedURLException e) {
			String msg = NLS.bind("The image path {0} in not a valid location the bundle {1}.", path, pluginId);
			throw new RuntimeException(msg, e);
		} catch (IOException e) {
			String msg = NLS.bind("The image {0} was not found in the bundle {1}.", path, pluginId);
			throw new RuntimeException(msg, e);
		}
	}

	private Label createTextLabel(Composite parent) {
		Label label = new Label(parent, SWT.WRAP);
		GridData gd = new GridData();
		gd.horizontalAlignment = SWT.FILL;
		gd.verticalAlignment = SWT.BOTTOM;
		gd.grabExcessHorizontalSpace = true;
		gd.grabExcessVerticalSpace = true;
		label.setLayoutData(gd);
		
		label.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
		label.setFont(parent.getDisplay().getSystemFont());
		
		if (nextMessage != null) {
			label.setText(nextMessage);
		}
		return label;
	}

	private Point getMonitorCenter(Shell shell) {
		Monitor primary = shell.getDisplay().getPrimaryMonitor ();
		Rectangle bounds = primary.getBounds();
		Rectangle rect = shell.getBounds();
		int x = bounds.x + (bounds.width - rect.width) / 2;
		int y = bounds.y + (bounds.height - rect.height) / 2;
		return new Point(x, y);
	}

	@Override
	public void close() {
		splashShell.close();
		splashShell = null;
	}

	@Override
	public void setMessage(final String message) {
		if (textLabel != null && !textLabel.isDisposed()) {
			splashShell.getDisplay().syncExec(new Runnable() {
				@Override
				public void run() {
					textLabel.setText(message);
					splashShell.layout();
					splashShell.update();
				}
			});
		} else {
			nextMessage  = message;
		}
	}
}

[Updated on: Thu, 26 April 2012 05:39]

Report message to a moderator

Re: Splash Screen with Progress Bar and Messages [message #884574 is a reply to message #857153] Mon, 11 June 2012 07:33 Go to previous messageGo to next message
Christoph Keimel is currently offline Christoph Keimel
Messages: 347
Registered: December 2010
Location: Germany
Senior Member
Bug 382224 - Suggestion for an E4 Splash Screen Service
Re: Splash Screen with Progress Bar and Messages [message #994516 is a reply to message #843741] Thu, 27 December 2012 09:53 Go to previous message
Joseph Carroll is currently offline Joseph Carroll
Messages: 174
Registered: May 2012
Location: Milwaukee, WI
Senior Member

Note to self:

Also look at Bug 382224

Previous Topic:NoClassDefFound - jexel
Next Topic:Workbench Eventing
Goto Forum:
  


Current Time: Mon Sep 01 07:38:32 EDT 2014

Powered by FUDForum. Page generated in 0.08842 seconds