本文转自:http://www.vogella.de/articles/EclipseRCP/article.html
Eclipse RCP
This tutorial describes how to develop Eclipse RCP applications. It is based on Eclipse 3.7 (Eclipse Indigo).
Table of Contents
-
1. Eclipse RCP Overview
2. Eclipse Plugin Architecture
-
-
2.1. Eclipse IDE vrs. Eclipse RCP
2.2. Plugins, OSGi, Extension Points
2.3. Main components of an Eclipse RCP application
2.4. Configuration files
3. Installation
-
-
3.1. Installation
3.2. Update an Eclipse Java IDE
4. Create your first RCP application
-
-
4.1. Create an RCP application
4.2. Start your RCP application
4.3. Convention
5. Startup process and Advisors
6. Run configuration
-
-
6.1. Overview
6.2. Check the runtime configuration
7. Views
-
-
7.1. Overview
7.2. Create a view
7.3. Add the view to your perspective
7.4. Result
7.5. Add view to perspective via code
7.6. Editor / View interaction
8. JFace Viewer
-
-
8.1. Overview
8.2. ComboViewer
9. Field Assist and label decorator
-
-
9.1. Field Assist and label decorator
9.2. Example
10. Products and Branding
-
-
10.1. Application versus Product
10.2. Product Configuration
10.3. Create your product configuration
10.4. Dependencies
10.5. Launch your product
10.6. Splash Screen
10.7. Branding your product
10.8. Customizing the start icon and launcher arguments
11. Deploy your product
12. Commands
-
-
12.1. Overview
12.2. Defining commands
12.3. Using commands in menus
13. Perspectives
-
-
13.1. Adding a perspective to your application
13.2. Select the perspective
14. System Tray
15. Adding a status line
-
-
15.1. Setup Status line
15.2. Shared Status Line
16. Tips and Tricks
-
-
16.1. Save users layout
16.2. Finding unused dependencies
16.3. Deploy your own JRE with your RCP application
16.4. Multi-User settings
17. Questions and Discussion
18. Links and Literature
-
-
18.1. Source Code
18.2. Eclipse Resources
18.3. vogella Resources
1. Eclipse RCP Overview
Eclipse RCP allows developers to use the Eclipse platform to create flexible and extensible desktop applications. Eclipse and Eclipse RCP applications are build upon a plugin architecture . Plugins are the smallest deployable and installable software components of Eclipse. A plugin is a collection of files and a configuration file (MANIFEST.MF) which describes the plugin and its dependencies.
This plugin architecture allows Eclipse and Eclipse RCP applications to get extended by third parties.
The following picture show the content of an example RCP application.
This tutorial will introduce you to the exciting world of development of Eclipse RCP applications.
2. Eclipse Plugin Architecture
2.1. Eclipse IDE vrs. Eclipse RCP
An Eclipse application consists out of plugins.
From the Eclipse RCP perspective the Eclipse IDE is only one collection of specific plugins. The components of the Eclipse IDE are primary the following.
An Eclipse RCP application use only parts of these components. An Eclipse RCP application typically uses:
For a headless Eclipse based applications (without UI) only the runtime is necessary.
The OSGi runtime provides the framework to run the modular application. SWT is the standard UI component library used by Eclipse and JFace provides some convenient API on top of SWT. The workbench provides the framework for your application. The workbench is responsible for displaying all other UI components.
2.2. Plugins, OSGi, Extension Points
As said Eclipse application are build via a collection of plugins. Plugins define their API and their dependencies. The basis for this architecture is the runtime environment Equinox which is the reference implementation of OSGi . Eclipse uses the term "Plugin" and OSGi uses the term "bundle", but both terms mean the same.
OSGi specifies how Eclipse plugins defines:
-
their API - public classes which can be used by other plugins
-
their dependencies - package or plugins which are required for the plugin to run correctly
OSGi defines also services. Please see the OSGi Tutorial for details.
In addition to the OSGi functionality you can also use and define extension-points in Eclipse applications. Extension-points define interfaces for other plugins to contribute functionality (code and non-code ).
Another or the same plugin can use extensions, e.g. provide functionality to these extension points.
Extensions and extension-points are described in the file "plugin.xml". This file is a XML file which provides a user interface for editing this file. The Eclipse IDE provides editors for this file (via Plugin Development Environment plugins).
Existing extensions (contributions) are collected during the start of an Eclipse RCP application. The information in the extension points is converted into so-called descriptors and stored in registries.
2.3. Main components of an Eclipse RCP application
The minimal required plugins to create and run an minimal Eclipse RCP application (with UI) are the two plugins "org.eclipse.core.runtime" and "org.eclipse.ui". Based on these components an Eclipse RCP application must define the following elements:
-
Main program - A RCP main application class implements the interface "IApplication". This class can be viewed as the equivalent to the main method for standard Java application. Eclipse expects that the application class is defined via the extension point "org.eclipse.core.runtime.application".
-
A Perspective - defines the layout of your application. Must be declared via the extension point "org.eclipse.ui.perspective".
-
Workbench Advisor- invisible technical component which controls the appearance of the application (menus, toolbars, perspectives, etc)
2.4. Configuration files
An Eclipse RCP application has two main configuration files.
-
MANIFEST.MF - contains the OSGi configuration information.
-
plugin.xml - Information about the extensions and extension points
3. Installation
3.1. Installation
On Eclipse.org , click on DOWNLOADS. Download the package "Eclipse for RCP and RAP Developers". Extract the download to your harddisk. Avoid having special characters or spaces in the path to Eclipse.
3.2. Update an Eclipse Java IDE
In case you have downloaded the Eclipse Java IDE (or any other non RCP flavor) distribution you can use the Eclipse Update Manager to install the plugins required for RCP development. See Eclipse Update Manager for details on using the update manager.
Install "General Purpose Tools" -> "Eclipse Plug-in Development Environment" and "Eclipse RCP Plug-in Developer Resources" from the Indigo update site. You may have to remove the "Group items by category" flag to see these features.
4. Create your first RCP application
The following explains how to create a simple RCP application. It assumes that you already have some knowledge in using the Eclipse IDE for standard Java development. See Eclipse IDE Tutorial if you don't have this knowledge.
4.1. Create an RCP application
In Eclipse select File-> New Project. From the list select "Plug-In Project".
Give your plugin the name "de.vogella.rcp.intro.first" .
Press "Next" and make the following settings. As we are going to develop an RCP application, select "Yes" at the question "Would you like to create a rich client application".
Press next and select the template "Hello RCP" .
Press next and select "Add branding" and press Finish.
As a result a project with the following project structure will be created. Have a look at the different files especially the Java files to get a first feeling about the project structure.
4.2. Start your RCP application
Open the file "MANIFEST.MF" by double-clicking on it. You should see an editor and the tab "Overview" should be selected. Click the link "Launch an Eclipse Application".
The result should look like the following:
Congratulations, you have created and started your first RCP application.
4.3. Convention
In this tutorial we will always create RCP applications. Therefore if the instruction says "Create an RCP project" you should create a new plugin project with the flag "Would you like to create a rich client application" enabled.
5. Startup process and Advisors
During the startup of an Eclipse RCP application the Eclipse runtime will evaluate which class is defined via the "org.eclipse.core.runtime.application" extension point. This class is typically called Application and must implement the interface IApplication.
The IApplication class will be loaded and creates and runs a Workbench. The Workbench is configured via a "WorkbenchAdvisor". The Workbench will start a "WorkbenchWindow" which is configured via a WorkbenchWindowAdvisor. This WorkbenchWindow will create the toolbar of the application which can get configured at startup via the "ActionBarAdvisor".
Each adviser allow to configure certain behavior of the application, e.g. the WorkbenchAdvisor allows to perform certain actions at startup or shutdown by overriding the methods preStartUp() and preShutdown().
6. Run configuration
6.1. Overview
A run configuration in Eclipse defines the environment under which a RCP application will be started. For example it defines compiler flags, plugin (classpath) dependencies etc. Sometimes a run configuration is called "launch configuration". If you start your RCP application a run configuration will be automatically created for you.
To see and edit your run configuration select the file "MANIFEST.MF", right-click on it and select -> Run As -> Run Configurations
In the field "location" you specify their the files will be created which are necessary to run your RCP application.
6.2. Check the runtime configuration
On the Plug-ins Tab select "Validate plug-ins prior to launching". This will check if you have all required plugins in your launch configuration. If this check reports that some plugins are missing, try clicking the "Add Required-Plug-Ins" button.
Tip
This may solve errors like "One or more bundles are not resolved because the following root constraints are not resolved" or "java.lang.RuntimeException: No application id has been found."
On the tab Arguments you find the parameter -consoleLog. This option allows to see errors in the RCP application in the console view and is very helpful to identify problems. .
Tip
Other nice parameters are -console (which will give you a OSGI console where you can check the status of your application) and -noExit (which will keep the OSGI console open even if the application ends / crashes).
7. Views
7.1. Overview
View are used to display information in an RCP application, they can also be used to change data. Views extends the abstract class "ViewParts".
The following will explain how to add views to your application. We will continue to use the RCP project "de.vogella.rcp.intro.first".
7.2. Create a view
Add the extension "org.eclipse.ui.views" to your plugin. Select ""plugin.xml" and the tab "Extentions". Right mouse-click on your new view extension and select New -> View. Maintain the id "de.vogella.rcp.intro.view.MyView" and the class "de.vogella.rcp.intro.view.MyView".
Create the class "MyView" by clicking on the "class" hyperlink and maintain the following code. Afterwards your view is ready to be used.
package de.vogella.rcp.intro.first; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.part.ViewPart; public class MyView extends ViewPart { @Override public void createPartControl(Composite parent) { Text text = new Text(parent, SWT.BORDER); text.setText("Imagine a fantastic user interface here"); } @Override public void setFocus() { } }
7.3. Add the view to your perspective
You have to add the view to your perspective. Add the extension "org.eclipse.ui.perspectiveExtensions" to your plugin.
Right click "*(perspectiveExtension)" -> New -> view". Maintain your view id "de.vogella.rcp.intro.first.MyView". Make the view relative to "org.eclipse.ui.editorss" which is the currently invisible editor area and make the view use all the space by selecting the maximum ratio of "0.95f".
7.4. Result
Run your application to see the result.
7.5. Add view to perspective via code
I personally prefer extension points over code. But instead of using the extension point "org.eclipse.ui.perspectiveExtensions" you could also add the view via code to the perspective. For this modify "Perspective.java" to the following.
package de.vogella.rcp.intro.view; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveFactory; public class Perspective implements IPerspectiveFactory { public void createInitialLayout(IPageLayout layout) { layout.addView("de.vogella.rcp.intro.first.MyView", IPageLayout.TOP, IPageLayout.RATIO_MAX, IPageLayout.ID_EDITOR_AREA); } }
7.6. Editor / View interaction
To learn how to use Eclipse Editors and how to communicate betweeen view and editor please see Eclipse Editors .
8. JFace Viewer
8.1. Overview
JFace provides also a viewers which allow to work with Java object directly to create an user interface. Viewers are available for trees, tables, lists and comboboxes. The following will show an example for the usage of comboviewer. You find details in the the usage of tableviewer can be found it JFaces Tables Tutorial and JFace Tree Viewer Tutorial .
8.2. ComboViewer
Continue to use the project "de.vogella.rcp.intro.first". Create the following Java class.
package de.vogella.rcp.intro.first; public class Person { private String firstName; private String lastName; public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
Change "MyView.java" to the following.
package de.vogella.rcp.intro.first; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.ui.part.ViewPart; public class MyView extends ViewPart { public static final String ID = "de.vogella.rcp.intro.jfaceviewer.view"; private ComboViewer viewer; public void createPartControl(Composite parent) { GridLayout layout = new GridLayout(2, false); parent.setLayout(layout); Label label = new Label(parent, SWT.NONE); label.setText("Select a person:"); viewer = new ComboViewer(parent, SWT.READ_ONLY); viewer.setContentProvider(new ArrayContentProvider()); viewer.setLabelProvider(new LabelProvider() { @Override public String getText(Object element) { if (element instanceof Person) { Person person = (Person) element; return person.getFirstName(); } return super.getText(element); } }); Person[] persons = new Person[] { new Person("Lars", "Vogel"), new Person("Tim", "Taler"), new Person("Jim", "Knopf") }; // Set set the input to the viewer this input will be send to the // content provider viewer.setInput(persons); // React to the selection of the viewer // Note that the viewer return the real object and not just a string // representation viewer.addSelectionChangedListener(new ISelectionChangedListener() { @Override public void selectionChanged(SelectionChangedEvent event) { IStructuredSelection selection = (IStructuredSelection) event .getSelection(); System.out.println(((Person) selection.getFirstElement()) .getLastName()); } }); // You can select a object directly via the domain object Person person = persons[0]; viewer.setSelection(new StructuredSelection(person)); } /** * Passing the focus request to the viewer's control. */ public void setFocus() { viewer.getControl().setFocus(); } }
If you run this example you application should look like the following.
This example uses a SWT Layout Manager. Find the details for this in SWT Tutorial.
9. Field Assist and label decorator
9.1. Field Assist and label decorator
Field Assist can be used to provide information about the possible inputs and status of a simple field, e.g. text field or combo box. The "org.eclipse.jface.fieldassist" package provides assistance in two ways: ControlDecorations and Content Proposals.
Control decorations allow you to place image decorations on SWT controls to show additional information about the control. These decorations can also have descriptions which are displayed once the user places the mouse over them. During the layout of your screen you need to make sure that enough space is available to display these decorations.
Content proposal allows to provide user input help for the possible choices for this field.
9.2. Example
Re-use the project "de.vogella.rcp.intro.first". In our example the content proposal should get activated via certain keys ("." and "#") as well as the key combination "CTRL+Space".
Change the View.java to the following.
package de.vogella.rcp.intro.first; import org.eclipse.jface.bindings.keys.KeyStroke; import org.eclipse.jface.bindings.keys.ParseException; import org.eclipse.jface.fieldassist.ContentProposalAdapter; import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.jface.fieldassist.FieldDecorationRegistry; import org.eclipse.jface.fieldassist.SimpleContentProposalProvider; import org.eclipse.jface.fieldassist.TextContentAdapter; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.part.ViewPart; public class MyView extends ViewPart { public void createPartControl(Composite parent) { GridLayout layout = new GridLayout(2,false); parent.setLayout(layout); Label label = new Label(parent, SWT.NONE); label.setText("Please select a value: "); Text text = new Text(parent, SWT.BORDER); createDeco(text, "Use CNTL + SPACE to see possible values"); GridData data = new GridData(GridData.FILL_HORIZONTAL); text.setLayoutData(data); ControlDecoration deco = new ControlDecoration(text, SWT.LEFT); deco.setDescriptionText("Use CNTL + SPACE to see possible values"); deco.setImage(FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_INFORMATION).getImage()); deco.setShowOnlyOnFocus(false); // Help the user with the possible inputs // "." and "#" will also activate the content proposals char[] autoActivationCharacters = new char[] { '.', '#' }; KeyStroke keyStroke; try { // keyStroke = KeyStroke.getInstance("Ctrl+Space"); // assume that myTextControl has already been created in some way ContentProposalAdapter adapter = new ContentProposalAdapter(text, new TextContentAdapter(), new SimpleContentProposalProvider(new String[] { "ProposalOne", "ProposalTwo", "ProposalThree" }), keyStroke, autoActivationCharacters); } catch (ParseException e) { e.printStackTrace(); } } public void setFocus() { } private void createDeco(Text text, String s){ } }
Run the application and check that the control decorations and the content proposal works.
10. Products and Branding
So far your RCP applications can only get started from Eclipse. To export an product you need to create a "product". This file defines the parts which make your application complete, including the resources which belong to your application.
10.1. Application versus Product
The equivalent of the Java main() method in Eclipse RCP is the "application". Applications are defined via the extension point "org.eclipse.core.runtime.applications". You can define many application but and only one can be started at a time.
A "product" defines all resources that goes with your application, e.g. icons, splash screen, external jars, other plugins, etc. The product is a development artifact which describes the content of your application and it not required at runtime.
10.2. Product Configuration
To create a product you need a product configuration. This configuration file contains all the information about required packages, configuration file, etc. The configuration file is used for exporting / creating your product.
10.3. Create your product configuration
We will continue to use the RCP project "de.vogella.rcp.intro.first". Right-click on your project and select New -> Product Configuration.
Name your product configuration "de.vogella.rcp.intro.first.product". Select "Create a configuration file with basis settings". Press finish.
Open the file de.vogella.rcp.intro.first.product" and select the "Overview" tab. Maintain the name "DeployTest". Leave the ID empty. The name is the default which will be displayed in the title of the window, the ID is not required and maintaining it leads sometimes to problems. You can change this default name in class ApplicationWorkbenchWindowAdvisor in the method preWindowOpen() via the configurer.setTitle("New title");)
Press "New" in the "Product Definition" part and select the application of your plugin "de.vogella.rcp.intro.first.application".
As a result the "Product Definition" part of the overview tab should now be filled with your selection.
The product identifier is stored as the extension "org.eclipse.core.runtime.product" in the file "plugin.xml".
10.4. Dependencies
A product can either be based on plugins or features . This setting is done on the overview tab. We will use a product definition based on plugins. See Eclipse Feature Project - Tutorial for details on how to create a feature project.
Switch to the "Dependencies" Tab and click "Add". Select the plugin "de.vogella.rcp.intro.first". Press the button "Add Required Plug-ins". Save.
10.5. Launch your product
On the overview tab press synchronize and then press "Launch an Eclipse application". Synchronize will align your product artifacts with the launch configuration.
Tip
If you receive the error "Dependent plug-in could not be loaded" or "Application could not be found" then you may have to adjust your launch configuration configuration. Open the launch configuration and press "Add required Plug-ins".
Tip
The launch configuration for your product is automatically created and updated based on your product configuration, e.g. the selected plugins. Changes in the launch configuration will not automatically update the product configuration.
10.6. Splash Screen
The tab "Splash" allows you to specify the plugin which contains the splash screen. You need to put the file "splash.bmp" into the project directory. The name and the format is hard-coded and cannot be changed. selecting the corresponding settings.
Create a "splash.bmp" via your favority graphics tool and save it in the project with contains the product. You can also add a message and a process bar to your splash screen by
If you start your application you should see your splash screen.
10.7. Branding your product
The standard Eclipse About Dialog can be branded. You can add an icon and / or and a text to your application. In this example I do not use this.
To show the "About dialog" add the standard command "org.eclipse.ui.help.about" to your menu. See Eclipse Commands Tutorial for information how to use Eclipse standard commands.
10.8. Customizing the start icon and launcher arguments
In this example I do not use this.
The launcher is the executable program that is created during the deployment of the product. Per default "eclipse.exe" with an "eclipse" icon is created. To change this select the launcher tab of your product configuration.
Here you can specify the name of the application and the icon which should be used. Make sure the deep of the icons is correctly maintained otherwise Eclipse will not use these icons.
In the launcher section you can also specify parameters to your Eclipse program or JVM arguments.
You created your product configuration. The next chapter will explain how to use this configuration to create an product, e.g. a stand- alone program which can be started outside of Eclipse.
11. Deploy your product
Your product configuration can be used to create a standalone RCP. You export the product and the result can be shared with other users. What will be included in the exported product is defined by the file "build.properties". Eclipse will automatically include the compiled classes via "build.properties". You have to manage manually the other files, e.g. icons or splash screens images.
What is included in the build is defined via the file "plugin.xml". Select "build.properties" (or plugin.xml and the "build" tab). Make sure the "META-INF "directory and the file "plugin.xml" and all other static files, e.g. icons, splash.bmp, are included in the output.
Switch to your product configuration file and select the tab Overview. Click on the "Eclipse Product export wizard" to export your product.
Maintain the target directory and press finish.
This should create a directory "eclipse" in the specified place with includes a file "eclipse.exe" which starts your application. Double click on it to start your application.
If you take the content of this directory and unzip on another machine (which has Java installed) your program should run there too. The export dialog allows to created a Archive file which you can the send directly to your users.
To learn how to automate the creation of a product please see Eclipse PDE Build .
12. Commands
12.1. Overview
A command is a declarative description of a component and is independent from the implementation details. A command can be categorized and a hot key (key binding) can be assigned to it. Commands can be used in menus, toolbars and / or context menus. The following will give demonstrates the usage of commands in menus. For details on commands see Eclipse Commands - Tutorial
Tip
Commands are superior to Actions. In my opinion Actions should be marked as depreciated. See Bug for deprecating Actions
12.2. Defining commands
We will create a command which will exit the application. Create a new RCP project "de.vogella.rcp.commands.first" using the "Hello RCP" template. Click on the plugin.xml and select the Extensions tab. Press the "Add" button.
Search for the extension "org.eclipse.ui.commands". Select it and press finish.
Create a new command by right-clicking on your extension point and by selecting New -> command.
Tip
If you only see an "Generic" entry you most likely have not downloaded "Eclipse for RCP/Plug-in Developers". Please see Eclipse Installation .
Set the ID to "de.vogella.rcp.commands.first.commands.Exit" and the name to "Exit". Enter the class "de.vogella.rcp.commands.first.commands.ExitHandler" as defaultHandler.
Press the hyperlink "defaultHandler" to create the class which should extend "org.eclipse.core.commands.AbstractHandler".
package de.vogella.rcp.commands.first.commands; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.ui.handlers.HandlerUtil; public class ExitHandler extends AbstractHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { HandlerUtil.getActiveWorkbenchWindow(event).close(); return null; } }
12.3. Using commands in menus
The command which we defined should be used in a menu. Add the extension point "org.eclipse.ui.menus" to your application similar to adding the extension "org.eclipse.ui.commands". Right click on the extension point and select new -> menuContribution.
Create a new menu contribution with the location URI "menu:org.eclipse.ui.main.menu". Make sure this URL is correct otherwise your menu will not be shown.
Right click your menucontribution and select New -> Menu. Add a menu with the label "File" and the id "fileMenu".
Select your menu, right-click on it, select New-> Command. Maintain your commandID. Set the label to "Exit" and the tooltip to "Exits the application".
Your work should result in a plugin.xml file which looks like the following.
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.4"?> <plugin> <extension id="application" point="org.eclipse.core.runtime.applications"> <application> <run class="de.vogella.rcp.commands.first.Application"> </run> </application> </extension> <extension point="org.eclipse.ui.perspectives"> <perspective name="RCP Perspective" class="de.vogella.rcp.commands.first.Perspective" id="de.vogella.rcp.commands.first.perspective"> </perspective> </extension> <extension point="org.eclipse.ui.commands"> <command defaultHandler="de.vogella.rcp.commands.first.commands.ExitHandler" id="de.vogella.rcp.commands.first.commands.Exit" name="Exit"> </command> </extension> <extension point="org.eclipse.ui.menus"> <menuContribution locationURI="menu:org.eclipse.ui.main.menu"> <menu id="fileMenu" label="File"> <command commandId="de.vogella.rcp.commands.first.commands.Exit" label="Exit" style="push" tooltip="Exit the application"> </command> </menu> </menuContribution> </extension> </plugin>
Run the example. You should see menu with the file and if you select the "Exit" entry you application should exit.
13. Perspectives
Perspectives group together and organize UI element that relate to a specific task. Eclipse RCP allows you to add perspectives to your application. The following presents an example.
13.1. Adding a perspective to your application
Create a new RCP project called "de.vogella.rcp.intro.perspective". Use the "RCP application with a view" as a template. In "plugin.xml" add a new extension point "org.eclipse.ui.perspectives". Give the perspective with the id "de.vogella.rcp.intro.perspective.perspective" and the name "vogella.de Perspective". Change the class name to "de.vogella.rcp.intro.perspective.Perspective".
Click on the "class*" link to create the class. The method createInitialLayout() in your new class is responsible for creating the new perspective. We re-use the existing view in the coding. After this step the perspective is defined but not yet reachable via the application.
package de.vogella.rcp.intro.perspective; import org.eclipse.ui.IPageLayout; import org.eclipse.ui.IPerspectiveFactory; public class Perspective implements IPerspectiveFactory { public void createInitialLayout(IPageLayout layout) { String editorArea = layout.getEditorArea(); layout.setEditorAreaVisible(false); layout.setFixed(true); layout.addStandaloneView(View.ID, false, IPageLayout.LEFT, 1.0f, editorArea); } }
13.2. Select the perspective
13.2.1. Select perspective via the toolbar / coolbar
You can activate the switch between perspectives the ApplicationWorkbenchWindowAdvisor in method preWindowOpen() with configurer.setShowPerspectiveBar(true);
package de.vogella.rcp.intro.perspective; import org.eclipse.swt.graphics.Point; import org.eclipse.ui.application.ActionBarAdvisor; import org.eclipse.ui.application.IActionBarConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.application.WorkbenchWindowAdvisor; public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { public ApplicationWorkbenchWindowAdvisor( IWorkbenchWindowConfigurer configurer) { super(configurer); } public ActionBarAdvisor createActionBarAdvisor( IActionBarConfigurer configurer) { return new ApplicationActionBarAdvisor(configurer); } public void preWindowOpen() { IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); configurer.setInitialSize(new Point(400, 300)); configurer.setShowStatusLine(false); configurer.setTitle("RCP Application"); configurer.setShowPerspectiveBar(true); } }
You should now be able to select your perspective interactively.
13.2.2. Select perspective via the menu
You can re-use the Eclipse perspective switch in a menu via the following standard command "org.eclipse.ui.perspectives.showPerspective". See Eclipse Commands.
14. System Tray
The following add an icon for the RCP application to the system tray and adds a menu to this icon. We add the functionality that if the window is minimized then the program is not visible in the taskpane (only via the tray icon).
Create a new project "de.vogella.rcp.intro.traytest". Use the "Hello RCP" as a template. Create a command which the id "de.vogella.rcp.intro.traytest.exitCommand" which exists the application.
Open the class "ApplicationWorkbenchWindowAdvisor" and maintain the following code.
package de.vogella.rcp.intro.traytest; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ShellAdapter; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tray; import org.eclipse.swt.widgets.TrayItem; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.application.ActionBarAdvisor; import org.eclipse.ui.application.IActionBarConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.application.WorkbenchWindowAdvisor; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.plugin.AbstractUIPlugin; public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { private IWorkbenchWindow window; private TrayItem trayItem; private Image trayImage; private final static String COMMAND_ID = "de.vogella.rcp.intro.traytest.exitCommand"; public ApplicationWorkbenchWindowAdvisor( IWorkbenchWindowConfigurer configurer) { super(configurer); } public ActionBarAdvisor createActionBarAdvisor( IActionBarConfigurer configurer) { return new ApplicationActionBarAdvisor(configurer); } public void preWindowOpen() { IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); configurer.setInitialSize(new Point(400, 300)); configurer.setShowCoolBar(false); configurer.setShowStatusLine(false); configurer.setTitle("Hello RCP"); //$NON-NLS-1$ } // As of here is the new stuff @Override public void postWindowOpen() { super.postWindowOpen(); window = getWindowConfigurer().getWindow(); trayItem = initTaskItem(window); // Some OS might not support tray items if (trayItem != null) { minimizeBehavior(); // Create exit and about action on the icon hookPopupMenu(); } } // Add a listener to the shell private void minimizeBehavior() { window.getShell().addShellListener(new ShellAdapter() { // If the window is minimized hide the window public void shellIconified(ShellEvent e) { window.getShell().setVisible(false); } }); // If user double-clicks on the tray icons the application will be // visible again trayItem.addListener(SWT.DefaultSelection, new Listener() { public void handleEvent(Event event) { Shell shell = window.getShell(); if (!shell.isVisible()) { window.getShell().setMinimized(false); shell.setVisible(true); } } }); } // We hook up on menu entry which allows to close the application private void hookPopupMenu() { trayItem.addListener(SWT.MenuDetect, new Listener() { public void handleEvent(Event event) { Menu menu = new Menu(window.getShell(), SWT.POP_UP); // Creates a new menu item that terminates the program // when selected MenuItem exit = new MenuItem(menu, SWT.NONE); exit.setText("Goodbye!"); exit.addListener(SWT.Selection, new Listener() { public void handleEvent(Event event) { // Lets call our command IHandlerService handlerService = (IHandlerService) window .getService(IHandlerService.class); try { handlerService.executeCommand(COMMAND_ID, null); } catch (Exception ex) { throw new RuntimeException(COMMAND_ID); } } }); // We need to make the menu visible menu.setVisible(true); } }); } // This methods create the tray item and return a reference private TrayItem initTaskItem(IWorkbenchWindow window) { final Tray tray = window.getShell().getDisplay().getSystemTray(); TrayItem trayItem = new TrayItem(tray, SWT.NONE); trayImage = AbstractUIPlugin.imageDescriptorFromPlugin( "de.vogella.rcp.intro.traytest", "/icons/alt_about.gif") .createImage(); trayItem.setImage(trayImage); trayItem.setToolTipText("TrayItem"); return trayItem; } // We need to clean-up after ourself @Override public void dispose() { if (trayImage != null) { trayImage.dispose(); } if (trayItem != null) { trayItem.dispose(); } } }
Run your application and see that you have a system tray icon. Test the menu and the minimized behavior. If the application is minized it should not be vislble in the taskbar but only in the system tray.
15. Adding a status line
15.1. Setup Status line
Create a new RCP project "de.vogella.rcp.intro.statusline". Use the "Hello RCP" as the template. Open the class "ApplicationWorkbenchWindowAdvisor" and change method preWindowOpen(). The relevant line in the coding is: "configurer.setShowStatusLine(true);"
package de.vogella.rcp.intro.statusline; import org.eclipse.swt.graphics.Point; import org.eclipse.ui.application.ActionBarAdvisor; import org.eclipse.ui.application.IActionBarConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.application.WorkbenchWindowAdvisor; public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) { super(configurer); } public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) { return new ApplicationActionBarAdvisor(configurer); } @Override public void preWindowOpen() { IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); configurer.setInitialSize(new Point(400, 300)); configurer.setShowCoolBar(false); configurer.setShowStatusLine(false); configurer.setTitle("Status Line Example"); configurer.setShowStatusLine(true); } }
If you run the application you should already see a status line. At this point the status line does not contain text.
15.2. Shared Status Line
The shared message area can be used by all parts of the application to write messages to this area.
Tip
Whole RCP application has access to the information in the shared status line therefore the information in the shared status line might be overwritten.
The following write a text to the status line.
package de.vogella.rcp.intro.statusline; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.swt.graphics.Point; import org.eclipse.ui.application.ActionBarAdvisor; import org.eclipse.ui.application.IActionBarConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.application.WorkbenchWindowAdvisor; public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor { public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) { super(configurer); } public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) { return new ApplicationActionBarAdvisor(configurer); } @Override public void preWindowOpen() { IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); configurer.setInitialSize(new Point(400, 300)); configurer.setShowCoolBar(false); configurer.setShowStatusLine(false); configurer.setTitle("Status Line Example"); configurer.setShowStatusLine(true); } // This is the new method @Override public void postWindowOpen() { IStatusLineManager statusline = getWindowConfigurer() .getActionBarConfigurer().getStatusLineManager(); statusline.setMessage(null, "Status line is ready"); } }
Run your application. You should now see the following.
Add a view with the implementation class "de.vogella.rcp.intro.statusline.ViewPart1" to your application and your perspective. This view contains a button to set the status line.
package de.vogella.rcp.intro.statusline; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IActionBars; import org.eclipse.ui.part.ViewPart; public class ViewPart1 extends ViewPart { boolean pressed = false; @Override public void createPartControl(Composite parent) { Button setStatusLine = new Button(parent, SWT.PUSH); setStatusLine.setText("Set Statusline "); setStatusLine.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { String message = "I would like to say hello to you."; if (pressed) { message = "Thank you for using me"; } setStatusLine(message); pressed = !pressed; } }); } private void setStatusLine(String message) { // Get the status line and set the text IActionBars bars = getViewSite().getActionBars(); bars.getStatusLineManager().setMessage(message); } @Override public void setFocus() { } }
If you run it the result should look like the following.
Tip
From an editor you can access the status line via the following:
IEditorPart.getEditorSite().getActionBars();
16. Tips and Tricks
16.1. Save users layout
To remember the user's layout and window size for the next time you start your application, add configurer.setSaveAndRestore(true); to the initialize method of ApplicationWorkbenchAdvisor.
package addactiontoview; import org.eclipse.ui.application.IWorkbenchConfigurer; import org.eclipse.ui.application.IWorkbenchWindowConfigurer; import org.eclipse.ui.application.WorkbenchAdvisor; import org.eclipse.ui.application.WorkbenchWindowAdvisor; public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor { private static final String PERSPECTIVE_ID = "AddActiontoView.perspective"; public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( IWorkbenchWindowConfigurer configurer) { return new ApplicationWorkbenchWindowAdvisor(configurer); } public String getInitialWindowPerspectiveId() { return PERSPECTIVE_ID; } @Override public void initialize(IWorkbenchConfigurer configurer) { super.initialize(configurer); configurer.setSaveAndRestore(true); } }
Eclipse has a pre-defined command to reset the perspective. See Eclipse Commands .
16.2. Finding unused dependencies
In the file plugin.xml (tab dependencies) you define on which plugins your plugin depends. Of course you should only define the required plugins here. You can check if you have any dependency maintained which is actually not used, by selecting Dependency Analysis -> Find unused dependencies.
16.3. Deploy your own JRE with your RCP application
YOu can also deploy your own RCP application to make sure that a certain JRE is used. An Eclipse RCP application first checks in the installation directory for a folder "jre" and for a contained Java-VM. If it find one then this JRE is used to start the Eclipse RCP application.
16.4. Multi-User settings
Eclipse RCP applications save configuration files in the folder ".metadata". In the standard settings the Eclipse RCP installation directory will be used for this folder. If several users are using the same installation folder, then you should supply the parameter "-data" to specify an alternative location. If you specify the value "@user.home/applicationname" the configuration will be saved in a user specific folder.
17. Questions and Discussion
Before posting questions, please see the vogella FAQ . If you have questions or find an error in this article please use the http://groups.google.com/group/vogella . I have created a short list how to create good questions which might also help you.
18. Links and Literature
18.2. Eclipse Resources
Eclipse RCP Book from Ralf Ebert (German))
SWT Graphics
Understanding Layout in SWT from Wayne Beaton
JFace Snippets (Codeexamples)
SWT Snippets (Code Examples)
18.3. vogella Resources
Eclipse RCP Training Join my Eclipse RCP Training to become an RCP Expert in 5 days (Training in German)
Android Tutorial Introduction to Android Programming
GWT Tutorial Program in Java and compile to JavaScript and HTML
Eclipse RCP Tutorial Create native applications in Java
JUnit Tutorial Test your application
Git Tutorial Put everything you have under distributed version control system