Eclipse e4 RCP Theming

Giving an Eclipse e4 application a new theme is rather easy with the e4 css theme support. There are many tutorials and articles about it.

And you can give your e4 RCP application a distinct theme. No problem there. But when you want to give your user the ability to switch themes that is a completely other story. Switching themes includes accessing the IThemeManager which is in the package org.eclipse.ui.themes. Still sounds easy enough. Importing the package as a dependency and add the bundle org.eclipse.ui.themes to the application build and we are all done.

Problem with this is that org.eclipse.ui.themes seems to depend on parts of the Eclipse IDE which you normally don't have in an Eclipse e4 RCP application. So this approach does not work.

There is a bundle with the symbolic name org.eclipse.ui.themes but it doesn't export the java package org.eclipse.ui.themes. The bundles contains the CSS and image files but no java package.

I found the package in the bundle org.eclipse.ui.workbench. What the f…!!! That is an Eclipse 3.x bundle.

So no IThemeManager for switching themes.

But if we can't switch themes dynamically perhaps we can load the correct theme on application start … and yes, that is possible. Long live the PartRenderingEngine.

import org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.ui.workbench.lifecycle.PostContextCreate;

public class LifeCycleManager {

	@PostContextCreate
	void postContextCreate(IEclipseContext context) {
		String cssURI = "platform:/plugin/miworkplace.ui.themes/css/dark.css";
		this.context.set(E4Workbench.CSS_URI_ARG, cssURI);
		PartRenderingEngine.initializeStyling(Display.getCurrent(), this.context);
	}
}

Update

This also works for setting/switching a theme.

The necessary classes can be found in the plugin org.eclipse.e4.ui.css.swt.theme.

@Inject
private IThemeManager themeManager;

IThemeEngine engine = themeManager.getEngineForDisplay(Display.getCurrent());
for (ITheme theme : engine.getThemes()) {
    if (theme.getId().equals(currentThemeId)) {
	engine.setTheme(theme, true);
	break;
    }
}