Eclipse Rich Client Platform with Eclipse Ganymede

Lars Vogel

 

Version 0.8

 

10.04.2008

Abstract

The Eclipse Rich Client Platform (RCP) allows developers to use the Eclipse architecture to design flexible and extensible applications re-using a lot of already existing functionality and coding patterns inherent in Eclipse. Getting started with Eclipse RCP can be time consuming and difficult. Having a short how-to-description makes it easier to get started. Hence the following article focuses on how to get certain aspects of Eclipse RCP into work.

Within this article Eclipse Ganymede (Eclipse 3.4) will be used. Please note that this article is currently in the process of getting updated from Eclipse Europa to Eclipse Ganymede. This update is not yet finished.

The following topics will be covered: Creating a first RCP application, creating menus and toolbars, views, editors, dialogs, usage of preferences and preferences pages, usage of external jars, creating a product and branding and adding help to an RCP application.

Each sections of this article tries to be as independent from the other parts as possible.


Table of Contents

1. Rich Client Platform
1.1. Overview 1.2. Eclipse RCP Architecture - Plug-ins, Extensions and Extension-Points 1.3. Application versus Product 1.4. Important files
2. Create your first RCP application
2.1. Create a RCP application 2.2. Plug-In ID in application 2.3. Start your RCP application
3. Launch configuration 4. Commands
4.1. Overview 4.2. Defining commands 4.3. Using commands in menus 4.4. Contribution to the View Toolbar 4.5. Contribution to the application coolbar 4.6. Context menu 4.7. Adding keybindings
5. System Tray 6. Views
6.1. Add the view template to your application 6.2. Add a view to your application
7. Working with Editors, View Interaction and Model Updates
7.1. Overview 7.2. Create project 7.3. Create and prepare the domain model 7.4. Use the domain model in the view 7.5. Adding the editor 7.6. Calling the editor 7.7. Providing the content to the editor
8. Dialog
8.1. Overview 8.2. Pre-defined dialogs 8.3. User defined dialogs
9. Wizards
9.1. Overview 9.2. Example
10. Preferences
10.1. Overview 10.2. Using preferences 10.3. Preference Page
11. Adding a status line
11.1. Setup Status line 11.2. Shared Status Line
12. Perspectives
12.1. Adding a perspective to your application 12.2. Making the perspective selectable via the user
13. Progress report 14. Deploy your product with external jars
14.1. Integrating external jars / third party libraries 14.2. Create a plug-in project for your jar
15. Tips and Trick
15.1. Save users layout 15.2. Get the display 15.3. Using the Eclipse Save Actions 15.4. Loading the model 15.5. Add the error log view to your RCP application
16. Making it a product
16.1. Overview 16.2. Create a product 16.3. Test your product
17. Branding
17.1. Splash Screen 17.2. Branding 17.3. Customizing the launcher
18. Deploy your product 19. Links and Literature
19.1. Eclipse Resources 19.2. Other Eclipse resources

1. Rich Client Platform

1.1. Overview

While Eclipse is a powerful development environment it can also be used to develop stand-alone general purpose applications which re-use the Eclipse framework.

For an brief introduction into Eclipse, the concepts and terminology (perspective, views, editors) please see Using the Eclipse Java IDE - Tutorial .

For Eclipse the whole RCP Application is a plug-in. A RCP application requires:

 

  • Main program

  • A Perspective

  • Workbench Advisor

 

 

A Workbench Advisor is an invisible technical component which controls the appearance of the application (menus, toolbars, perspectives, etc). Views are technical not required for a RCP application (but an RCP without views would not be very rich).

All plug-ins must provide a so-called manifest named "plugin.xml".

A RCP application extends the class org.eclipse.core.runtime.application. This represents the main program. The perspective is extended from org.eclipse.ui.perspective.

Also required are the two central plug-ins: org.eclipse.core.runtime and org.eclipse.ui

1.2.  Eclipse RCP Architecture - Plug-ins, Extensions and Extension-Points

The most important architectural characteristics of Eclipse is the Plug-in architecture. The Eclipse IDE is build as a number of plug-ins which are dependent on each other.

Plug-ins are the smallest deployable and installable software components of Eclipse.

Each plug-in can define so-called extension-points which define possibilities for functionality contributions ( code and non-code ) by other plug-ins. Non-code functionality contributions are for example the provision of help content.

A plug-in can use extensions, e.g. provide functionality to these extension points. In general an extension point can be used several times (either by the same plug-in or by other plug-ins).

The basis for this architecture is the runtime environment of Eclipse which is based on the OSGI Alliance. Eclipse used the OSGI reference implementation Equinox to run upon. The Plug-in concept of Eclipse is the same as the bundle concept of OSGI. Generally speaking a OSGI bundle equals a Plug-in and vice-versa.

The used extensions and the provided extension-points are described in the file plugin.xml. This file is a xml file which can be edited via the PDE (Plug-in Development Environment) which provides a nice user interface for editing this xml file.

Eclipse RCP provides and uses the same framework as the Eclipse Workbench hence allowing the programmer to divide the application functionality into several plug-ins, to use existing extension points and to provide additional extension points. This concept of Eclipse allows every programmer to structure his RCP application into several independent components and to easily declare extensions to existing extensions points.

1.3. Application versus Product

To run an Eclipse RCP program you have to define an application . The application can be seen as the main() method of a standard Java program. If this application shuts down the complete program is terminated.

In Eclipse terms a product is everything that goes with your application, e.g. icons, splash screen, external jars, other plug-ins, etc.

1.4. Important files

Some of the configuration files may be hidden by a filter. In the package explorer select the drop-down menu and then Filter to remove the filter for .* resources.

The plug-in manifest ties all the code and the resources together and is split on two files MANIFEST.MF" and plugin.xml .

The OSGi bundle manifest is stored in MANIFEST.MF.

 

The PDE provides an editor for editing the "MANIFEST.MF" and "plugin.xml".

In addition to these files you have the .project file. The .project contains the description of your project to re-created it, e.g. after import into another workspace. It contains a XML tag "natures" where the nature of the project is described. A plug-in project has the nature "org.eclipse.pde.PluginNature" and a java project has the nature "org.eclipse.jdt.core.javanature". These tags will also steer some behavior of the development environment, e.g. a project with PluginNature will update the java class path if you change the dependency information in a plug-in project.

2. Create your first RCP application

The following gives a quick guide on how to create a simple RCP application.

2.1. Create a RCP application

In Eclipse select File-> New Project. From the list select Plug-In Project.

Then perform the following steps:

Give your RCP plugin a name, e.g. "MyFirstRCP" .

 

 

Make the following settings. As we are going to develop a RCP application, select "Yes" at the question "Would you like to create a rich client application".

 

 

As a template select the "Hello RCP" .

 

 

On the next screen 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.

 

 

2.2. Plug-In ID in application

The plug-in ID is usually needed in several places, so it is a good idea to declare it as static in Application.java. This ID must be the same as defined in the field "ID" of the overview tab of plugin.xml. The ID is case sensitive.

For example if your RCP application is called MyFirstRCP add the following declaration to Application.java.

 

				
public static final String PLUGIN_ID = "MyFirstRCP";
			

 

2.3. Start your RCP application

Search in the menu path for the file "MANIFEST.MF" and double-click on it. You should see an editor and the tab "Overview" should be selected. Click the link "Launch an Eclipse Application".

 

Tip

Alternatively you can run your Eclipse RCP application by selecting the automatically created "plugin.xml", right mouse click and select "Run as" -> "Eclipse Application".

 

The result should look like the following:

Congratulations, you have created your first RCP application.

3. Launch configuration

A Launch configuration in Eclipse defines the environment under which your application will be started, e.g. compiler flag, plug-in (classpath) dependencies etc.

Select your plugin.xml -> Run As -> Run Configurations

 

 

 

 

You can specify the location of the Workspace Data. In this location the directory and the files required to run your RCP application will be created.

On the tab Arguments you should add the parameter -consoleLog. This will send error message of your Eclipse RCP application to your Eclipse development IDE. Otherwise you will not necessary know that your Eclipse RCP application has a problem.

 

Tip

Always add the parameter -consoleLog as an argument.

 

 

 

On the Plug-ins Tab select "Validate plug-ins prior to launching". This will check if you have all required plug-ins in your launch configuration. If this check reports that some Plug-ins are missing, try clicking the "Add Required-Plug-Ins" button.

 

Tip

Always set the flag "Validate plug-ins prior to launching".

 

 

 

4. Commands

4.1. Overview

As of Eclipse 3.3. it is recommended to use the commmand API to define menus, pop-up menu items and toolbars.

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 the command.

4.2. Defining commands

Our first example will be a command which will exit the application. Create a new project "Command Test" and use the "Hello RCP" Template (see Create your first Eclipse RCP application for details).

You need the extension org.eclipse.ui.commands. Click on the plugin.xml and select the Extensions tab.

 

 

Press the add button and search for the extension extension org.eclipse.ui.commands. Select it and press finish.

 

 

Create a new command by right-clicking New -> command.

 

 

Set the ID to "exit.command" and the name to "Exit". Enter the class commandtest.handler.ExitHandler as defaultHandler.

 

 

Press the hyperlink "defaultHandler" to create this class.

Choose org.eclipse.core.commands.AbstractHandler as Superclass.

 

 

 

Tip

IHandler defines the following methods which can be implemented:
  • isEnabled: Called during instantiation, defines if this action is enabled

  • isHandled: Defines if the handler can be called or not

  • execute: Coding which perform the action

  • fireHandlerChanged: needs to be called if isEnabled is changed.

 

Implement the following coding

 

				
package commandtest.handler;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.ui.handlers.HandlerUtil;

public class ExitHandler extends AbstractHandler implements IHandler {

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		HandlerUtil.getActiveWorkbenchWindow(event).close();
		return null;
	}

}

			

 

 

Tip

The class HandlerUtil provides access methods to the important Eclipse services.

 

You have correctly implemented the command. This command can now be used in various placed in your application.

 

Tip

Instead of using the default handler in the command you could also have used the "org.eclipse.ui.handlers"

 

4.3. Using commands in menus

The command which we just defined should now be used in a new menu.

Add the extension point "org.eclipse.ui.menu" to your application. Select therefore again plugin.xml and the tab "Extensions". Press Add, select the extension point "org.eclipse.ui.menu" and press Finish.

 

 

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".

  • menu: Extension of the menu of the application

  • toolbar: Extension of the toolbar of a view

  • popup: A context menu

 

 

Tip

The first part of the location URI defines what kind of menu contribution this is:

 

 

Tip

Make sure the URL must is correct, otherwise the menu will not get displayed.

 

 

 

 

 

Right click your menucontribution and select New -> Menu. Add a menu with the label "File" and the id "mymenu".

 

 

 

 

Now select your menu, right-click on it and select New-> Command. Maintain here the commandID you used earlier. Choose also a label.

 

 

If you the example you should see menu with the file. Selecting Exit should end your application.

 

 

4.4. Contribution to the View Toolbar

You can also add to the view toolbar. Create a new plug-in project "CommandViewContribution" with the template "RCP application with a view". Run the project to see the user interface.

Change Perspective.java to the following (a standalone view does not have a own toolbar.

 

				
package commandviewcontribution;

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.addView(View.ID,  IPageLayout.LEFT, 1.0f, editorArea);
	}

}

			

 

Switch to plugin.xml and add a new command with the id "hello.command" with default handler "handler.HelloHandler" and create the following coding for the handler.

 

				
package handler;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.ui.handlers.HandlerUtil;

public class HelloHandler extends AbstractHandler implements IHandler {

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		MessageDialog
		.openInformation(HandlerUtil.getActiveWorkbenchWindow(event).getShell(), "Info", "Info for you");

		return null;
	}

}

			

 

Add the extension point org.eclipse.ui.menus (fill out the ID and the name) and create a new menu contribution with the locationURI: "toolbar:CommandViewContribution.view".

 

Tip

toolbar tells the system to add it to the toolbar while the second argument is the id of your view (CommandViewContribution.view).

 

Create then a new command for this menucontribution and set the commandid to "hello.command" and the id to hello.menu. Assign the label "Hello" to it. Run it and it should show the contribution in the view.

 

 

Run the application to see your new view contribution.

 

 

4.5.  Contribution to the application coolbar

Lets add the command from the last section also to the application coolbar. Therefore you add a new menucontribution to your org.eclipse.ui.menus extension point and you call it "toolbar:org.eclipse.ui.main.toolbar".

 

 

Add a toolbar to your menu contribution.

 

 

Add then a command to it, again using the ID hello.command. Assign a label and an icon to it.

You need also to activate the coolbar in your application. Switch to ApplicationWorkbenchWindowAdvisor.java and turn the coolbar on via configurer.setShowCoolBar(true);

 

				
package commandviewcontribution;

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.setShowCoolBar(true);
		configurer.setShowStatusLine(false);
	}
}

			

 

The result should look like the following:

 

 

4.6.  Context menu

Now lets try to add a ContextMenu to a table. Create a new project CommandContextMenu based on the "RCP with a view" example.

Create a new command "showselected.command" with the default handler "handler.ShowSelectedHandler".

Add a new menuContribution with the locationURI "popup:CommandContextMenu.view", where "popup:CommandContextMenu.view" is the ID of your view which has been automatically created for you.

Right click your new menuContribution and select New -> Command. Assign the commandID "showselected.command". Label it "List selected".

Now you have add a MenuManager to your view. Select View.java and in the method createPartControl add the following:

 

				
	public void createPartControl(Composite parent) {
		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL);
		viewer.setContentProvider(new ViewContentProvider());
		viewer.setLabelProvider(new ViewLabelProvider());
		viewer.setInput(getViewSite());
		// This is new code
		// First we create a menu Manager
		MenuManager menuManager = new MenuManager();
		Menu menu = menuManager.createContextMenu(viewer.getTable());
		// Set the MenuManager
		viewer.getTable().setMenu(menu);
		getSite().registerContextMenu(menuManager, viewer);
	}

			

 

Implement now the coding for your handler. I just print the selected elements to the console.

 

				
package handler;

import java.util.Iterator;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;

public class ShowSelectedHandler extends AbstractHandler implements IHandler {

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {
		ISelection selection = HandlerUtil.getActiveWorkbenchWindow(event)
				.getActivePage().getSelection();
		if (selection != null & selection instanceof IStructuredSelection) {
			IStructuredSelection strucSelection = (IStructuredSelection) selection;
			for (Iterator iterator = strucSelection.iterator(); iterator.hasNext();) {
				Object element = (Object) iterator.next();
				System.out.println(element.toString());
			}
		}
		return null;
	}

}

			

 

Run your application. On right mouse click the menu should be visible. If you select it menu then the names of the selected items should be writen to the console.

4.7.  Adding keybindings

Via keybindings you can define shortcuts for your commands.

Create a new project "CommandKey", declare command "hello.command" with a handler which does something, e.g. prints out "Hello" to the console

Right mouse click on the command extension and select New-> "keybinding"

 

 

Maintain the following settings. The "keyConfigurationId" define the validity of the keybinding. "org.eclipse.ui.defaultAcceleratorConfiguration" is the workbench default and will make sure you keybinding is valid in the whole application. The commandId is the ID of the command you just created (in our example "hello.command"). The key sequence is the shortcut key for calling the command. M1 represents the Cntr key.

 

 

If you now run it the keybinding should work and if you press Cntrl+1 the message on the console should be visible.

5. System Tray

In the following we will add a system tray icon, add the functionality that if the window is minimized then the program is not visible in the taskpane (only via the tray icon) and we will add a menu with some actions to the system tray icon.

To get a tray icon you need a Display. A display is an SWT object that represents the underlying graphics system. This object is available as of method postWindowOpen() in ApplicationWorkbenchWindowAdvisor.

Create a new project "TrayTest" (see Create your first Eclipse RCP application for details). Use the "Hello RCP application" as a template.

Define your application ID as "TrayTest" in Application.java.

 

			
import org.eclipse.equinox.app.IApplication;


public class Application implements IApplication {

	public static final String PLUGIN_ID = "TrayTest";
	......
		

 

Your project should have already a folder with icons. Check what you have icon "alt_about.gif" available.

Maintain the following code in class ApplicationWorkbenchWindowAdvisor. Note that you have to finished also the next part of the coding implementation, only this change will leave syntax errors. These will be gone after you make the change in "ApplicationActionBarAdvisor".

 

			
package traytest;

import org.eclipse.jface.action.MenuManager;
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.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.plugin.AbstractUIPlugin;

public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {

	private TrayItem trayItem;
	private Image trayImage;
	private IWorkbenchWindow window;
	public ApplicationActionBarAdvisor actionBarAdvisor;

	public ApplicationWorkbenchWindowAdvisor(
			IWorkbenchWindowConfigurer configurer) {
		super(configurer);
	}

	public ActionBarAdvisor createActionBarAdvisor(
			IActionBarConfigurer configurer) {
		actionBarAdvisor = new ApplicationActionBarAdvisor(configurer);
		return actionBarAdvisor;
	}

	public void preWindowOpen() {
		IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
		configurer.setInitialSize(new Point(400, 300));
		configurer.setShowCoolBar(false);
		configurer.setShowStatusLine(false);
		configurer.setTitle("Hello RCP");
	}

	@Override
	public void postWindowOpen() {
		super.postWindowOpen();
		window = getWindowConfigurer().getWindow();
		trayItem = initTaskItem(window);
		if (trayItem != null) {
			// The following coding will will the program if the program is
			// minimized
			// Not always desired
			createMinimize();
			// Create exit and about action on the icon
			hookPopupMenu();
		}
	}

	private void hookPopupMenu() {
		trayItem.addListener(SWT.MenuDetect, new Listener() {

			public void handleEvent(Event event) {
				MenuManager trayMenu = new MenuManager();
				Menu menu = trayMenu.createContextMenu(window.getShell());

				actionBarAdvisor.fillTrayItem(trayMenu);
				menu.setVisible(true);
			}

		});
	}

	private void createMinimize() {
		window.getShell().addShellListener(new ShellAdapter() {
			public void shellIconified(ShellEvent e) {
				window.getShell().setVisible(false);
			}
		});
		trayItem.addListener(SWT.DefaultSelection, new Listener() {
			public void handleEvent(Event event) {
				Shell shell = window.getShell();
				if (!shell.isVisible()) {
					shell.setVisible(true);
					window.getShell().setMinimized(false);
				}
			}
		});

	}

	private TrayItem initTaskItem(IWorkbenchWindow window) {
		final Tray tray = window.getShell().getDisplay().getSystemTray();
		TrayItem trayItem = new TrayItem(tray, SWT.NONE);
		trayImage = AbstractUIPlugin.imageDescriptorFromPlugin(
				Application.PLUGIN_ID, "/icons/alt_about.gif").createImage();
		trayItem.setImage(trayImage);
		trayItem.setToolTipText("TrayItem");
		return trayItem;

	}

	public void dispose() {
		if (trayImage != null) {
			trayImage.dispose();
			trayItem.dispose();
		}
	}

}

		

 

Now create the actions and the method fillTrayItem.

 

			
package traytest;

import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.application.ActionBarAdvisor;
import org.eclipse.ui.application.IActionBarConfigurer;

public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
	private IWorkbenchAction exitAction;

	private IWorkbenchAction aboutAction;

    public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
        super(configurer);
    }

    protected void makeActions(IWorkbenchWindow window) {
    	exitAction = ActionFactory.QUIT.create(window);

		register(exitAction);

		aboutAction = ActionFactory.ABOUT.create(window);

		register(aboutAction);

    }

    protected void fillMenuBar(IMenuManager menuBar) {
    }

	public void fillTrayItem(MenuManager trayMenu) {
		 trayMenu.add(aboutAction);
		 trayMenu.add(exitAction);
	}
    
}

		

 

Run your application and see that you have a system tray icon. Test the menu and the minimized behavior.

6. Views

Views provide information for a given task. A view is typically used to navigate a hierarchy of information, open an editor, or display properties for the active editor. The following will explain how to add views to your application.

6.1. Add the view template to your application

Create a new project "ViewTemplateTest" (see Create your first Eclipse RCP application for details). Use the "Hello RCP" as a template.

Select your plugin.xml and select the extension tab. Press the "Add" button. Select the extension wizard tab.

Follow the following steps:

 

 

 

 

 

 

 

 

Change the ID of your new view to viewtemplatetest.views.MyTemplateView.

 

 

If you run the application the new view is not displayed. To use the view you have to have to add it in method createInitialLayout of class Perspective. The first parameter of addView is the ID which you defined in your plugin.xml.

 

				
package viewtemplatetest;

import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;

public class Perspective implements IPerspectiveFactory {

	public void createInitialLayout(IPageLayout layout) {

		layout.addView("viewtemplatetest.views.MyTemplateView", IPageLayout.TOP,
				IPageLayout.RATIO_MAX, IPageLayout.ID_EDITOR_AREA);
	}
}
			

 

Run the application and see that the view is displayed.

 

 

Note: If the view should not be closeable add the following setting to the view: layout.getViewLayout("myplugin.views.MySampleView1").setCloseable(false); or if all views not not be closeable call setFixed(true) on the layout inside method createInitialLayout(); A fixed perspective makes the view not resizable and closeable. Also views can not be moved.

6.2. Add a view to your application

Create a new project "ViewTest" Create your first Eclipse RCP application for details). Use the "Hello RCP" as a template.

Select the file plugin.xml and the tab extensions. Press the "add" button and add org.eclipse.ui.views as an extension.

 

 

Right mouse-click on your new view extension and select New -> View

 

 

Maintain the ID ViewTest.MyNewView and the class viewtest.MyNewView.

 

 

Create the class of the view by clicking on the class hyperlink.

 

 

Maintain the following code in your new class.

 

				
package viewtest;

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 MyNewView extends ViewPart {

	public MyNewView() {
		// TODO Auto-generated constructor stub
	}

	@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() {
		// TODO Auto-generated method stub

	}

}

			

 

In Perspective.java add your new view.

 

				
package viewtest;

import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPerspectiveFactory;

public class Perspective implements IPerspectiveFactory {

	public void createInitialLayout(IPageLayout layout) {
		layout.addView("ViewTest.MyNewView", IPageLayout.TOP,
				IPageLayout.RATIO_MAX, IPageLayout.ID_EDITOR_AREA);
	}
}

			

 

Run the application.

 

 

7.  Working with Editors, View Interaction and Model Updates

7.1. Overview

In the following we create a project which demonstrate the usage of editors and its interaction with an view. We are also going to see how an application can access an external domain model and how a domain model can notify views and editors about changes.

We will create a simple application with a view which shows first and last name of a list of persons. Once the user double-clicks on the name an editor is opened in which the user can edit the name.

The following data model makes the assumption that the last name of a person is unique. This assumption is of course not true in the real world.

7.2. Create project

Create a new project "EditorTest" (see Create your first Eclipse RCP application for details). Use the "RCP application with a view" as a template.

 

 

7.3. Create and prepare the domain model

Create a package mydomain. Create class MyModel.java in this package.

 

				
package mydomain;

import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class MyModel {

	private List<Person> persons = new ArrayList<Person>();
	private List<PropertyChangeListener> listener = new ArrayList<PropertyChangeListener>();

	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;
			notifyListeners();
		}
	}

	public List<Person> getPersons() {
		return persons;
	}

	public MyModel() {
		// Just for testing we hard-code the persons here:
		persons.add(new Person("Lars", "Vogel"));
		persons.add(new Person("Jim", "Knopf"));
	}

	private void notifyListeners() {
		for (Iterator iterator = listener.iterator(); iterator.hasNext();) {
			PropertyChangeListener name = (PropertyChangeListener) iterator
					.next();
			name.propertyChange(null);

		}
	}

	public void addChangeListener(PropertyChangeListener newListener) {
		listener.add(newListener);
	}

}

			

 

Create a new package editortest.contentProvider

Create a new class "MyContentProvider" which implements the interface IStructuredContentProvider.

 

 

Adjust the coding according to the following example:

 

				
package editortest.contentProvider;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import mydomain.MyModel;

import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;

public class MyContentProvider implements IStructuredContentProvider,
		PropertyChangeListener {

	private MyModel content;
	private final Viewer viewer;

	public MyContentProvider(Viewer viewer) {
		this.viewer = viewer;
		content = new MyModel();
		content.addChangeListener(this);
	}

	@Override
	public Object[] getElements(Object inputElement) {
		return content.getPersons().toArray();
	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub
	}

	@Override
	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
		// TODO Auto-generated method stub
	}

	@Override
	public void propertyChange(PropertyChangeEvent arg0) {
		viewer.refresh();
	}

}

			

 

Create a new class "MyLabelProvider" which implements the interface ILabelProvider. Use the following code.

 

				
package editortest.contentProvider;

import mydomain.MyModel.Person;

import org.eclipse.jface.viewers.ILabelProvider;

import org.eclipse.jface.viewers.ILabelProviderListener;

import org.eclipse.swt.graphics.Image;

import org.eclipse.ui.ISharedImages;

import org.eclipse.ui.PlatformUI;

public class MyLabelProvider implements ILabelProvider {

	@Override
	public Image getImage(Object element) {
		return PlatformUI.getWorkbench().getSharedImages().getImage(
				ISharedImages.IMG_OBJ_ELEMENT);
	}

	@Override
	public String getText(Object element) {
		Person person = (Person) element;
		return (person.getLastName());
	}

	@Override
	public void addListener(ILabelProviderListener listener) {
		// TODO Auto-generated method stub
	}

	@Override
	public void dispose() {
		// TODO Auto-generated method stub
	}

	@Override
	public boolean isLabelProperty(Object element, String property) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void removeListener(ILabelProviderListener listener) {
		// TODO Auto-generated method stub
	}
}

			

 

7.4. Use the domain model in the view

Change the class View to use your new content providers.

 

				
package editortest;

import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

import editortest.contentProvider.MyContentProvider;
import editortest.contentProvider.MyLabelProvider;

public class View extends ViewPart {
	public static final String ID = "EditorTest.view";

	private TableViewer viewer;

	/**
	 * This is a callback that will allow us to create the viewer and initialize
	 * it.
	 */
	public void createPartControl(Composite parent) {
		viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL
				| SWT.V_SCROLL);
		viewer.setContentProvider(new MyContentProvider(viewer));
		viewer.setLabelProvider(new MyLabelProvider());
		viewer.setInput(getViewSite());
	}

	/**
	 * Passing the focus request to the viewer's control.
	 */
	public void setFocus() {
		viewer.getControl().setFocus();
	}
}
			

 

Run your application. The view should now display the last names for your content provider. Currently nothing happens if you click on the names.

7.5. Adding the editor

Go to plugin.xml and select the tab extensions. Add the extension org.eclipse.ui.editors. Do not use a template. Use the ID "editortest.editors.MyNameEditor", any name you want and the class "editortest.editors.MyNameEditor".

Make also sure to select an icon! Otherwise your editor will not work.

 

 

 

 

Click on the class hyperlink to create the class. Create the following class. Important is the class variable "ID" which we will later use to reference to this class. The variable ID must match the id defined in the editor extension.

 

				
package editortest.editors;

import org.eclipse.core.runtime.IProgressMonitor;
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.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;

public class MyNameEditor extends EditorPart {
	public static final String ID = "editortest.editors.MyNameEditor";
	private Text text1;
	private Text text2;

	public MyNameEditor() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		// TODO Auto-generated method stub

	}

	@Override
	public void doSaveAs() {
		// TODO Auto-generated method stub

	}

	@Override
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		setSite(site);
		setInput(input);
		setPartName(input.getName());

	}

	@Override
	public boolean isDirty() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean isSaveAsAllowed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void createPartControl(Composite parent) {

		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		parent.setLayout(layout);
		Label label1 = new Label(parent, SWT.BORDER);
		label1.setText("First Name");
		text1 = new Text(parent, SWT.BORDER);
		Label label2 = new Label(parent, SWT.BORDER);
		label2.setText("Last Name");
		text2 = new Text(parent, SWT.BORDER);
	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

}

			

 

In package editortest.editors create a new class "MyNameEditorInput" which implements IEditorInput.

 

 

Change the created code the the following. It is important to note that the class which implements IEditorInput is a light-weight representation of the model. It should not contain the model. We cover this later (via view and editor linking).

It is recommended to overwrite the method equals and hashcode in an implementation of IEditorI. Based on the equals method the system will determine if the corresponding editor is already open or not.

 

				
package editortest.editors;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IPersistableElement;

public class MyNameEditorInput implements IEditorInput {

	private final String lastname;

	public MyNameEditorInput(String lastname) {
		this.lastname = lastname;

	}

	@Override
	public boolean exists() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public ImageDescriptor getImageDescriptor() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getName() {
		return lastname;
	}

	@Override
	public IPersistableElement getPersistable() {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IEditorInput#getToolTipText()
	 */
	@Override
	public String getToolTipText() {
		return "My Tool Tip";
	}

	@Override
	public Object getAdapter(Class adapter) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean equals(Object obj) {
		if (super.equals(obj)) {
			return true;
		}
		if (obj instanceof MyNameEditorInput) {
			return lastname.equals(((MyNameEditorInput) obj).getName());
		}
		return false;
	}

	@Override
	public int hashCode() {
		return lastname.hashCode();
	}

}

			

 

7.6. Calling the editor

Add an action to your view which opens a new editor every time a new item is double-clicked. The view makes his viewer available as selection provider via the following line:" getSite().setSelectionProvider(viewer);". This make is possible for other components, e.g. editors or views to register them as listeners to changes of the view. After opening a editor we also sending out this change to the listeners via "viewer.setSelection(viewer.getSelection());". We will later register the editor as listener. Change therefore the code of View.java to the following.

 

				
package editortest;

import mydomain.MyModel.Person;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchPage;
import org.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Eclipse中设置日文语言界面,可以按照以下步骤进行操作: 1. 首先,确保你已经下载并安装了日文语言包。你可以在Babel项目的官方网站上找到语言包的下载链接。根据引用,你可以使用以下链接下载日文语言包:http://download.eclipse.org/technology/babel/babel_language_packs/BabelLanguagePack-eclipse-zh_3.5.0.v20090620043401.zip 2. 下载完成后,打开Eclipse。在Eclipse的菜单栏上,点击"Help"(帮助)选项,并选择"Install New Software"(安装新软件)。 3. 在弹出的对话框中,点击"Add"(添加)按钮,并输入一个名称(比如"Language Packs")和对应的下载链接。根据引用,你可以使用以下链接:http://download.eclipse.org/technology/babel/babel_language_packs/ganymede.php 4. 点击"OK"(确定)按钮,并选择刚才添加的链接。确保在"Work with"(使用)下拉菜单中选择了刚才添加的链接。 5. 在下方的列表中,找到并勾选日文语言包。然后点击"Next"(下一步)按钮,按照提示完成安装过程。 6. 安装完成后,重新启动Eclipse。在启动后的欢迎页面或者菜单栏上,点击"Window"(窗口)选项,并选择"Preferences"(首选项)。 7. 在弹出的对话框中,展开"General"(常规)选项,然后选择"Appearance"(外观)子选项。在右侧的窗格中,找到"Language"(语言)下拉菜单,并选择"Japanese"(日文)选项。 8. 点击"Apply and Close"(应用并关闭)按钮,保存设置并关闭对话框。 现在,你的Eclipse界面就已经被设置为日文语言了。请注意,这些步骤是基于引用中提供的信息,并假设你已经安装了Eclipse软件。如果你还没有安装Eclipse,请先下载并安装它,然后按照以上步骤进行设置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [eclipse界面语言的切换方法](https://blog.csdn.net/fableking/article/details/1528906)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [eclipse 中日文系统 汉化](https://blog.csdn.net/pathfinder163/article/details/4970799)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值