Eclipse Plugin Development TUTORIAL
Eclipse Plugin Development TUTORIAL
Eclipse Plugin Development TUTORIAL
Eclipse Plugin Development Tutorial website to teach you how to develop eclipse plugins using
simple examples to a complex eclipse rcp over time. This chapter will give you a detailed insight into
Eclipse Architecture and we will develop a simple but fully functional eclipse plug-in so as to give you a
quick start with eclipse plug-in development.
Overview
Eclipse isn’t a huge single java program, but rather a small program which provides the functionality
of typical loader called plug-in loader. Eclipse (plug-in loader) is surrounded by hundreds and
thousands of plug-ins. Plug-in is nothing but another java program which extends the functionality of
Eclipse in some way. Each eclipse plug-in can either consume services provided by other plug-in or
can extend its functionality to be consumed by other plug-ins. These plug-in are dynamically loaded
An Open Platform
Eclipse is an open platform. It is designed to be easily and infinitely extensible by third parties. At the
core is the eclipse SDK, we can build various products/tools around this SDK. These products or tools
can further be extended by other products/tools and so on. For example, we can extend simple text
editor to create xml editor. Eclipse architecture is truly amazing when it comes to extensibility. This
extensibility is achieved by creating these products/tools in form of plug-ins.
Figure 1-1
RCP: On the bottom is RCP which provides the architecture and framework to build any rich client
application.
IDE: It is a tools platform and a rich client application itself. We can build various form of tooling by
using IDE for example Database tooling.
PDE: It provides all tools necessary to develop plug-ins and RCP applications. This is what we will
concentrate on the course of this tutorial.
Plug-ins everywhere
All the layers in eclipse SDK are made up of plug-ins. If you see all the way, you will notice that
everything is a plug-in in eclipse sdk.
Figure 1-3
Plug-in Architecture
A plugin is a small unit of Eclipse Platform that can be developed separately. It must be noted that all
of the functionality of eclipse is located in different plugins (except for the kernel)
A plug-in can be delivered as a jar file. A plug-in is self-contained bundle in a sense that it contains
the code and resources that it needs to run for ex: code, image files, resource bundles etc. A plug-in is
self describing - when I say it is self describing it means that it describes who it is and what it
contributes to the world. It also declares what it requires from the world.
ECLIPSE PLUG IN DEVELOPMENT (PAGE 2)
Figure 1-7
We all know that eclipse is extensible. In order to achieve this extensibility eclipse uses the concept of
extension points and extension. Think of extension point as Electric socket and think of extension as a
plug. Plug-in A exposes a extension point (electric socket) which Plug-in B extends by providing an
extension (an electric plug). Plug-in A knows nothing about plug-in B. If we think about it this is very
similar to concept of Inheritance – we extend functionality of base class to provide more specific
implementation. Think of Plug-in A as a text editor and Plug-in B as xml editor. Text editor declares
extension point thereby declaring to the world that it is open for extension and xml editor extends text
editor by using its extension point to customize it in its own way. It is important to understand that
each extension point essentially declares
a contract. An extension point provider only accepts those extensions which abide by the contract.
These extension points and extensions are declared in plugin.xml (discussed earlier). The runtime is
able to wire extensions and extension points and form a registry using markup alone.
Plug-in Example
Now that we have covered good amount of architecture basics, its time to get our hands dirty with
some actual plug-in coding. The process for creating a plug-in is best demonstrated by implementing a
plug-in on which discussion and examples can be based. Here we will take a step-by-step approach to
create a simple but fully operational plug-in. This example will try to give you an feel of eclipse plug-in
development. However, don’t try to grab all the details at this point. It is fine if you are not able to
understand much of the details in this example. Rest of the tutorial will cover all the topics in great
depth.
We will build a simple Resource Manager plug-in. Features of this plug-in are as follows:
Note: All Examples in this tutorial have been implemented using Eclipse version 3.1.2
Creating a Plug-in
1. Launch Eclipse.
2. From File menu, select New Project. This will open up New Project wizard.
3. Now select Plug-in Project and click on the next button. (see Figure 1-8)
Figure 1-8
4. On next page of the wizard (see Figure 1-9), enter the name of the project "com.myplugin.rmp"
Figure 1-9
5. Fill in the other fields as shown and then click the Next button. The next wizard page displays
options for generating plug-in Java class. Fill all the fields as shown below. Do not fill anything in
classpath field - This has been removed in eclipse 3.4. Plug-in Activator is required if we want to do
anything on plug-in start up or shut down. For example we want to acquire some resources at plug-in
start up and perform clean up when plug-in is shutdown. It is important to note that Eclipse startup
does not essentially means that your plug-in is starting up. Plug-ins are loaded/started only when they
are demanded or required. So activator is used when plug-in startup/shutdown happens.
Figure 1-10
6. Click Next, select Plug-in with a view and then click the Next button.
Figure 1-11
7. Next, Enter the values for this page (see Figure 1-12), and click the Next button.
Figure 1-12
8. Finally, uncheck all the options (see Figure 1-13). and click Finish button.
ECLIPSE PLUGIN TUTORIAL (PAGE 3)
After completing New plug-in Project wizard following directory structure will be created (Figure 1-14).
Figure 1-14
• RmpPlugin.java – This is the main plug-in class. When plug-in is activated, startup method of
this class is called. This class can be used to initialize plugin specific resources.
• ResourceManagerView.java – This is the View class which gets generated. This class
contributes to the UI of our example Resource manager plug-in.
• MANIFEST.MF – defines runtime information of the plugin
• Plugin.xml – defines the extension information of the plug-in.
In order to open up plug-in manifest editor double click on MANIFEST.MF or plugin.xml file. Browse
through the tabs shown at the bottom of editor. Don’t worry if you are unable to understand all of the
content in this editor, it will be discussed during course of this tutorial.
Figure 1-15
In This section a plug-in must list all the dependent plug-ins which are required so that our plug-in
compiles. As you know that we build our plug-ins on top of other plug-ins, so this section essentially
declares all those dependencies.
It must be noted that all above plug-in dependencies must be met before plug-in is resolved. It is
always good to scan your dependencies from time to time and remove unused dependencies. In order
to know unused dependencies use Dependency Analysis section.
Figure 1-16
On this page plug-in declares what all it exposes to the outside world. Lets understand this concept
with an example. Say you are building Plug-in A. Now if plug-in B wants to extend plug-in A or wants
to use plug-in A in any way it will be required that Plug-in A exposes its API’s. It is here that Plug-in A
would declare all the packages which it wants to expose to outside world. You can use Add.. button to
see all your plug-in packages and then select all Packages which you would like to export.
Another important section on this page is the Classpath. If your plug-in is using some external jars
then it is important to add such jars to runtime classpath. Note that simply adding such jars to project
classpath will only help you in compiling your source code. In order to make these jars available to
runtime environment use Classpath section.
Extensions page is a viewer on top of plugin.xml. This is one of the most frequently used page in plug-
in development. This page makes it easy to create extensions as this page is aware of all the
extension points. Eclipse provides around 213 extension points where clients can contribute
functionality. Extension points are available for virtually every thing for ex: builders, editors,
preferences, help contents, markers, views, perspective and so on. Basically we select some extension
point and then use these to build our own extensions.
This page is also a viewer on top of plugin.xml. This page is used to define our own extension points.
Such extension points define a contract which other plug-ins may agree to abide by and extend plug-
ins functionality in some way.
There are two ways to test this plug-in. First, we can build a product which will essentially create a
plugin bundle, this bundle is then dumped into plug-in folder of eclipse installation. Second, launching
new plug-in from within Overview tab of manifest editor. At this time we will take second approach to
test this plug-in. This is also the preferable choice when we are developing eclipse plug-ins and need
to test them from time to time. In order to test this plug-in click on Overview tab followed by clicking
on link Launch an Eclipse Application. See figure 1-19
Figure 1-19
This will launch another instance of eclipse application. However, this new instance will have our plug-
in registered with it, So we will be able to see resource manager view. After New Eclipse has started,
from the Window menu, select Show View > Other... to open the Show View dialog (see Figure 1-20).
In the dialog, expand the Resource Manager Category, select Resource Manager View, and then click
the OK button. This causes the Resource Manager view to open (see figure 1-21).
Figure 1-20
Figure 1-21
SWT Widgets
SWT provides a rich set of widgets that can be used to create either stand-alone Java applications or
Eclipse plug-ins. We will start by implementing a small SWT example before getting into details about
each of the widgets you are likely to use. In order to create this standalone version of swt program we
will start by creating new java Project in eclipse.
Before you can start using SWT, the SWT libraries need to be added to your project's classpath. To
add SWT support, do the following:
1. Download SWT library. For 3.1.2 version of eclipse, SWT library is available at
http://archive.eclipse.org/eclipse/downloads/drops/R-3.1.2-200601181600/index.php Look for the
section titled SWT Binary and Source.
2. From main menu tool bar, select "File" followed by "Import". Doing so will bring up the "Import
wizard" dialog.
3. Now select "Existing Projects into Workspace" and click on "Next" button.
4. Click on "Select archive file" followed by "Browse" button. Now locate the SWT archive that you
downloaded in step 1.
5. Click the Finish button to finish importing the SWT project into your workspace.
6. Create new java project from File > New Java Project.
7. Right-click on the project and select the Properties command to open the Properties dialog.
8. Select the Java Build Path followed by Projects tab and click the Add button.
9. Select the org.eclipse.swt project and click OK to finish adding the SWT libraries to your project's
classpath
1 import org.eclipse.swt.*;
2 import org.eclipse.swt.graphics.*;
3 import org.eclipse.swt.widgets.*;
Lines 1-3: SWT classes are contained in different packages which begin with org.eclipse.swt. The
package org.eclipse.swt is the main package and contains SWT class and exception/error classes. All
the SWT widgets are contained in org.eclipse.swt.widgets package. Refer to online help for more
information about these packages
Line 6: Every SWT program has a Display. Display acts like a bridge between program and underlying
operating system
Lines 7-9: Next, in the program we have created a shell. All the Top level windows are created by the
class Shell and shell's are contained in Display.
Line 10: When a shell is created it is invisible by default. Shell becomes visible only when method
open() is called on shell instance. open() method not only makes shell visible but also brings it to the
front so that all user input can be intercepted by the shell.
Lines 11-14: SWT supports an event based user interface. Event driven user interface essentially
means that user interaction events are generated which are then intercepted by eclipse application to
perform various actions. Not surprisingly, any event driven UI requires an event loop that continously
listens to user interface events and then broadcasts the events to interested parties. Example of such
event could be "Button click", "Minimize Window" etc. The condition when this event loop ends depend
upon the application For ex: in some cases user might close the window OR clicks on the exit button
provided by the application.
Line 15: Next, we are disposing the Display. Disposing display will release all resources that were
acquired by the running program in its lifetime.
In order to run this example program use the Run As > "SWT Application". This will open up new
window with title “First Example”.
Events
As discussed earlier, SWT supports an event based user interface. These events are generated by user
actions. User actions could be keyboard entry, button click, mouse drag etc. We can trap or listen to
these events by adding/attaching listeners to various SWT controls. Following listing shows an
example to attach selection listener to button widget
final Button myButton = new Button(shell, SWT.PUSH);
In order to know more about events and widgets which support each of these events refer to online
Platform Plug-in Developer Guide. Look for headings Low level events and High level events.
All the widgets have been defined in org.eclipse.swt.widgets package. In This section we will discuss
most commonly used widgets. Most likely you will use these widgets during eclipse plug-in
development. Best way to learn these widgets is through examples, so ill focus this discussion based
on examples. You can refer to SWT API document for further reading. All API’s are self explanatory
and quite simple.
1. Label Widget
Labels are used to display text messages/labels. Labels do not take part in event model and hence do
not generate user interaction events.
Buttons are used to generate special event called selection event when pressed or released. While
creating a button we can use different styles so that this control represent different type of UI
element. For example, we can use SWT.ARROW to create arrow button widget or SWT.CHECK to
create checkbox.
3. Text Widget
Eclipse plugin text field widget is used to take user input. It automatically shows scroll bar if
provided text is more then control’s length.
4. Combo Widget
Eclipse plugin Combo widget helps in displaying multiple options to user. User is allowed to select
single option from the list of options.
public class MyCombo {
public static void main(String[] args) {
Display myDisplay = new Display();
Shell myShell = new Shell(myDisplay);
myShell.setText("My Combo");
myShell.setBounds(120, 120, 220, 120);
myShell.setLayout(new FillLayout(SWT.VERTICAL));
final Combo myCombo = new Combo(myShell,SWT.READ_ONLY);
myCombo.setItems(new String[]
{"option1", "option2", "option3", "option4",
"option5"});
myCombo.setText("option5");
myCombo.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent event) {
System.out.println("you selected me: " +
myCombo.getText());
}
});
myShell.open();
while (!myShell.isDisposed()) {
if (!myDisplay.readAndDispatch()) myDisplay.sleep();
}
myDisplay.dispose();
}
}
5. Table Widget
Table widget is used to display items in rows and columns. The columns of a table are defined by
TableColumn.
6. Tree Widget
The tree widget is used to display data in a hierarchical manner. Typically tree has many tree items.
For understanding purposes you can call tree item an "Tree Parent" if this item contains other items.
Tree parent can contain other Tree Parents. or simply leaf nodes. A user navigates through a tree by
expanding and collapsing items.
7. Menu Widget
The Menu widget is used to display user set of actions. Typical example of menu is the file menu on
top of this browser window. Menu can further contain submenu’s and so on.
8. Composite Widget
This is a very important widget since it is used to group together all other widgets. Composite widget
can be used as a container for other widgets. We can use layout managers (Discussed next) for
positioning and placement of other widgets inside composite widget.
SWT defines many different types of layouts which are helpful in positioning and sizing of child widgets
in a composite. In the following SWT Layout Tutorial Next we will discuss four type of layouts
available in SWT.
1. Fill Layout
Fill layout is the simplest layout. It is used to layout widgets in a single row or column forcing them to
be of same size.
public MyFillLayout() {
FillLayout fillLayout = new FillLayout(SWT.VERTICAL);
fillLayout.marginHeight = 5;
fillLayout.marginWidth = 5;
fillLayout.spacing = 1;
myShell.setLayout(fillLayout);
myShell.pack();
myShell.open();
while (!myShell.isDisposed()) {
if (!myDisplay.readAndDispatch()) {
myDisplay.sleep();
}
}
myDisplay.dispose();
}
2. Row Layout
Row Layout provides more options as compared to fill layout, which provide more control Row Layout
has a number of configuration fields which can be used to control placement of the widget. In
addition, the height and width of each control in a RowLayout can be specified by setting a RowData
object into the control using setLayoutData()
3. Grid Layout
SWT Gridlayout is to arrange children in a grid of rows and columns, We have many options to
control the sizing of each child widget.
myShell.open();
while (!myShell.isDisposed()) {
if (!myDisplay.readAndDispatch()) myDisplay.sleep();
}
myDisplay.dispose();
}
}
4. Form Layout
Instances of this class control the position and size of the children of a composite control by using
FormAttachments to optionally configure the left, top, right and bottom edges of each child. It is one
of the most powerful layout managers.
We have already seen SWT in action. It helps in rapid application development by providing ready
made widgets like Tree, Table etc. However, there is a severe limitation in using these widgets
directly. Let me explain it with an example. Consider the table example in SWT chapter. Following
lines of code were used to populate Table with one row of data.
You can see that we have used String Literals "A1" and "A2" respectively while creating a row in table.
If you think from object oriented perspective it is a severe limitation. In object oriented world we talk
in terms of Objects. In order to build above table we will have to get Strings out of those objects and
then supply it to Table to form every single row. Isn’t there a way in which we can simply map objects
to tables so that table can itself use those objects and populate itself? This is where JFace viewers
step in to provide OO wrappers around their associated SWT widgets. JFace provides two types of
Viewers, Text Viewers and List Viewers. First we will discuss about list viewers.
List Viewers
JFace list viewers, such as TableViewer and TreeViewer, allow you to directly use your business
objects (Employee, Customer, User, Business etc.) without. The trick is to provide adapters for things
such as retrieving an item's name/label OR for retrieving an Tree parent's children (tree widget). So
we will talk about these adaptors first before moving onto implementing Table/Tree Viewers.
1. Label Providers
A label provider maps an element of the viewer's model to an optional image and optional text string
used to display the element in the viewer's control.
The two most frequently used label providers are ILabelProvider and ITableLabelProvider In order to
display elements name and label we can use getImage and getText methods provided by
ILabelProvider Similarly in case of ITableLabelProvider, in order to display label image and label text
for any column in a table we can use getColumnImage and getColumnText. We can use
setLabelProvider() method to attach/associate provider with the viewer.
2. Content Providers
A content provider is another common adapter type used in list viewers. This provider is used to feed
the actual content to the viewer. Viewer then uses its internal logic to display these input elements
with its internal controls.
The two most frequently used content providers are IStructuredContentProvider and
ITreeContentProvider. These adapters provide convienient methods to retrive child elements for a
given element. We can use setContentProvider() method to attach/associate provider with the viewer.
A intial domain/business model of the application can be associated with the viewer with the help of
setInput() method.
3. Viewer Sorters
A viewer sorter is a adapter which is called by viewer before the elements/contents are displayed to
the user. We can use this provider to sort the elements which are provided by the content provider.
We can use setSorter() method on the viewer to attach sorter.
As the name suggests a viewer filter is used to filter out some of the elements from original list of
elements provided by the content provider. For example: Original list of Employees consist of
employees with two type of roles Admin, Non admin. We can use filters to display only admin role
users. We can attach viewer filter by using the setFilter() method on the viwer itself.
Table Viewers
The TableViewer class acts as a OO wrapper around the Table widget. Table Viewer is capable of
displaying data in rows and cloumns with the help of adapters like label provider and content provider.
Table Viewer provides many useful APIs, Please refer to online Eclipse Platform API Specification
myTableViewer.setLabelProvider(
new ExampleLabelProvider());
myTableViewer.setContentProvider(
new ArrayContentProvider());
myTableViewer.setInput(Example.getInput());
exampleShell.open();
while (!exampleShell.isDisposed()) {
if (!exampleDisplay.readAndDispatch())
exampleDisplay.sleep();
}
exampleDisplay.dispose();
}
In Above listing we are creating table viewer Then we are creating two columns namely "Hello" and
"Bye" The header of each column is set using setText() method. There after label provider and content
providers are being attached with the viewer. Following listing shows how the label provider looks like
String bye;
Tree Viewers
The treeViewer class acts as a OO wrapper around the Tree widget. Tree Viewer is capable of
displaying data in hierarchical manner with the help of adapters like label provider and content
provider.
Tree Viewer provides many useful APIs, Please refer to online Eclipse Platform API Specification
myTreeViewer.setLabelProvider(
new MyTreeLabelProvider());
myTreeViewer.setContentProvider(
new MyTreeContentProvider());
myTreeViewer.setInput(Example1.getInput());
exampleShell.open();
while (!exampleShell.isDisposed()) {
if (!exampleDisplay.readAndDispatch())
exampleDisplay.sleep();
}
exampleDisplay.dispose();
}
In above code listing we are creating the tree viewer. There after we are configuring label and content
adapters. Following listing shows the rest of code:
Example1(String name){
this.name = name;
}
As most of you who are Eclipse users will know, you can easily organize your views around in each
perspective to make yourself comfortable with development related tasks. As an Eclipse user the first
thing you do when you launch eclipse application is to select a perspective which is most suitable for
the job in hand. In this chapter we will create a new perspective which will open up Resource manager
view when selected. Since our plug-in is very small with only one view, creating a perspective for the
purpose of opening up single view might look overburden. However, in real world Plug-in applications
Views can grow real big in terms of number, so creating a perspective and managing views become
almost a necessity.
What is a Perspective?
A perspective is useful in organizing various eclipse views around the editor area, these are also
helpful in managing menus and toolbars We can save perspectives and these can be switched to in
future. As an eclipse plugin developer we can either create a new perspective from scratch or enhance
existing perspective. Enhancing existing perspective essentially means to accommodate your view in
an existing perspective for example: we can add our resource manager view to existing Resource
perspective, so that it opens up when ever user selects resource perspective.
Eclipse comes with many inbuilt perspectives (Some of them are listed below):
Resource - This perspective shows various workspace resources irrespective of file extension.
Following figure shows how Java Browsing perspective looks like. Notice how different views Projects
view, Packages view etc. are organized in screen below. So the whole purpose of creating perspective
can be to organize your screens according to ease of use.
Figure 4-1
Creating a Perspective
In order to create perspective, open the Resource Manager’s Eclipse plugin manifest editor, Now
select the Extensions tab. In Extensions tab click the Add button. Now select
org.eclipse.ui.perspectives from the list in the New Extension wizard. Click the Finish button.
Figure 4-2
Again go to the Extensions page in the plug-in manifest editor, open mouse right click context menu
on the org.eclipse.ui.perspectives extension followed by selecting New > perspective. This will add a
new perspective called “com.myplugin.rmp.perspective1”. Modify properties on right side as shown in
the figure below.
Figure 4-3
Perspective factories
Now we will create perspective factory which will be used to define the layout of our newly created
perspective Click on the "class" link on the right side of the class property and use Java Attribute
Editor to create a new class.
Figure 4-4
Open the ResourceManagerPerspectiveFactory class and modify it as follows so that the Resource
Manager view will appear below the editor area and the standard Outline view will be shown to its left.
package com.myplugin.rmp;
import org.eclipse.ui.IPerspectiveFactory;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IFolderLayout;
myLayout.addView(IPageLayout.ID_OUTLINE,IPageLayout.LEFT,0.
30f,
myLayout.getEditorArea());
IFolderLayout bot =
myLayout.createFolder(BOTTOM,IPageLayout.BOTTOM,0.76f,
myLayout.getEditorArea());
bot.addView(VIEW_ID);
}
}
Open Manifest editor if not already open. Select Overview tab > Launch an eclipse application. It will
launch separate eclipse application.
Open our new perspective from Window > Open Perspective > Other (as shown below)
Figure 4-5
Select Resource Manager perspective and click ok button. This will switch the perspective to our newly
created perspective as shown below
Figure 4-7
As discussed earlier, in addition to creating new perspective we can also use already existing
perspectives and add our views to it. For example we may want to open Resource Manager view
whenever Java Perspective or Resource Perspective is opened up. In this section we will discuss how
to enhance an existing perspective such that it accommodates our view in its existing view
arrangement.
First, open the Resource Manager’s plug-in manifest editor, Next, click on the Extensions tab followed
by clicking the "Add" button. Now select org.eclipse.ui.perspectiveExtensions (as shown below) from
the list extension points. Next, Click the Finish button
Figure 4-8
Next, again go to the Extensions page of manifest editor, Open right click context menu on the
org.eclipse.ui.perspectiveExtensions. Select New > perspectiveExtension. This will add a perspective
extension named “com.myplugin.rmp.perspectiveExtension1”. Modify Properties as shown in the figure
below.
Figure 4-9
On the Extensions page, click on the org.eclipse.ui.resourcePerspective extension and select New >
view. Modify Extension element details as shown in figure below.
Figure 4-10
Open Manifest editor if not already open. Select Overview tab > Launch an eclipse application. It will
launch separate eclipse application.
Open Resource Perspective and you will see that Resource Manager view is shown.
Figure 4-11
Actions
Action represent user actions such as “Run”, “Debug”, “Save to file”, “Search” or “Go to marker”.
Actions are attached to buttons, tool/menu bars in an eclipse application. Actions run method is called
whenever end user clicks on menu item or button. This chapter covers all this with examples that
show how to use actions and action sets in the example Resource Manager plug-in.
Following figure shows the many areas where a plug-in can contribute actions. It includes Context
menu of a view or editor, to local toolbar and pull down menu of a view, to the main toolbar and menu
bar of the workbench window. In course of this tutorial we will add actions to various places in
workbench window. However, at this time some of these actions may not do anything useful other
then displaying some pop up message or opening up resource manager view. During the course of this
tutorial we will re-visit these actions to add more meaningful implementation.
Figure 5-1
Now we will add a menu to the main menu bar and a button to the main toolbar. Both of these open
the Resource manager view when clicked by the user. Open the Resource Manager plug-in manifest
editor, Next navigate to Extensions page followed by clicking on the "Add" button.
Select org.eclipse.ui.actionSets from the list an then Click on the Finish button.
Figure 5-2
Navigate back to the Extensions page. Open right click context menu on the org.eclipse.ui.actionSets
item and select New > actionSet (See Image below).
Figure 5-3
Once new com.myplugin.rmp.actionSet1 is added, Select this action set and modify its properties as
shown below.
Figure 5-4
Next, add a menu to the main menu bar by opening up the right click context menu on on the action
set followed by selecting New > menu (As shown below)
Figure 5-5
Next, Select the menu and modify its properties as shown below. Notice the path attribute, we have
specified its value as “additions”. For now don’t worry about this attribute, we will discuss it in section
to follow.
Figure 5-6
When working with menu’s we often define groups. So we will have menu’s - which will have groups
and actions will be added to groups. So first some groups need to be defined. Two types of groups are
available – Separator and groupMarker. A separator group displays a horizontal line. We will now
create both of these groups. First we create a groupMarker by opening up right click context menu on
Resource Manager menu and select New followed by groupMarker. Select the groupMarker and change
its name to "content" Next define second group to the Resource Manager menu; by selecting New
followed by separator and change its name to "additions".
Figure 5-7
We will use this groups when we create actions discussed next. Take a minute to look back at path
attribute which we provided at the time of creating menu inside action set. We defined “additions” in
the path attribute, this is nothing but a predefined group.
Next, we will define the action itself. Open right click context menu on the Resource Manager
ActionSet and select New followed by action. Modify action properties as shown below:
Figure 5-8
Almost every attribute is self descriptive, However following attributes require special attention:
toolbarPath: We have entered "Normal/additions" to this attribute. The first part is the id of toolbar
where we would like to add this action. Note that eclipse has only single toolbar and its id is “Normal”.
Second part is again a predefined group in toolbar. So the complete statement specifies that we would
like to add this action to Normal toolbar under additions group.
Action delegate is a class which implements the behavior associated with the action. All above steps
have no meaning until we specify the behavior associated with the action. When we say behavior, it
essentially means what action will be triggered when user clicks on the menu item or toolbar button.
Next, we will create a action delegate class.
Click on the "class" link on the left of the class Text Box.
Figure 5-9
Clicking the class label will open up the Java Attribute Editor for the action's class.
In Package text box, provide "com.myplugin.rmp.actions" and
"OpenResourceManagerViewActionDelegate" as Name. Click on the Finish button.
Figure 5-10
package com.myplugin.rmp.actions;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWindowActionDelegate;
import org.eclipse.ui.PartInitException;
public class OpenResourceManagerViewActionDelegate implements
IWorkbenchWindowActionDelegate {
try {
} catch (PartInitException e) {
}
}
public void selectionChanged(IAction action, ISelection
selection) {}
}
launch the Runtime Workbench. You will see that action have been added to main menu bar and a
push button has been added to main toolbar. Clicking on anyone of these will open up Resource
Manager View.
Figure 5-11
In this section we will add actions to out Resource Manager View. In order to add these actions, open
the Resource Manager plug-in manifest editor, navigate to Extensions tab and click the "Add" button.
Select org.eclipse.ui.viewActions from the list. Click the Finish button to add this extension to the
plug-in manifest.
Figure 5-12
Next, right click and add viewActions > New > viewContribution.
Figure 5-13
Next, modify the viewContribution attributes as shown below, Notice that the targetID attribute points
to the ID of the view to which we are adding this action. In this example the target view is Resource
Manager View.
Figure 5-14
Next, Right click on the ResourceManagerViewContribution > New > Action to create a new action
which will be associated with the View toolbar. Provide action attributes as shown below.
Figure 5-15
Action delegate is a class which implements the behavior associated with the action. Next, we will
create a action delegate class.
Click on the class: label that appears to the left of the class field to create a new action delegate class.
We will modify the class so that it opens up a pop up when action is clicked on the View tool bar.
package com.myplugin.rmp;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
public class ResourceManagerViewActionDelegate implements
IViewActionDelegate {
private IViewPart view;
Launch the Runtime Workbench. You will see a new push button has been added to Resource Manager
View tool bar. It will open up a Message box when clicked (See Below).
Figure 5-16
Dialogs
Dialogs are almost always used in every application. Dialogs are used to either inform user or to take
user input. In Eclipse dialogs can be broadly classified into two categories i.e. SWT dialogs and JFace
Dialogs. We will discuss how to create dialogs in eclipse plugins starting with Introduction to
SWT Dialogs.
SWT Dialogs
Figure 6-1
Dialog class is an abstract class from which you can derive concrete native dialogs. The SWT already
contains some concrete subclasses of dialog, such as shown in table below:
Subclass Description
ColorDialog Dialog for selecting a color
DirectoryDialog Dialog for selecting a directory in host file system
Dialog for selecting a file in host file system. Supported
FileDialog
styles are SWT.OPEN and SWT.SAVE
FontDialog Dialog for selecting text font
Dialog for displaying a message. Various style
parameters govern which buttons will be displayed to
the user For ex: SWT.OK, SWT.CLOSE etc.
MessageBox
Icon to be displayed with the message can be governed
by styles such as SWT.ICON_ERROR,
SWT.ICON_QUESTION etc.
PrintDialog Dialog for selecting printer and for printer settings
JFace Dialogs
Figure 6-2
The package org.eclipse.jface.dialogs provides classes that implement standard Dialog. All these
classes are subclasses of abstract class Dialog which itself is a subclass of abstract class Window.
Following table describes some of the most commonly used subclasses of Jface Dialog.
Subclass Description
superclass of dialogs with an icon and a
IconAndMessageDialog
message.
SelectionDialog superclass for displaying a selection
StatusDialog superclass for dialogs with status bar
TitleAreaDialog dialog having a title area.
ErrorDialog A dialog to display errors
MessageDialog dialog class for showing messages to the user.
A dialog which prompts for one element out of a
ListDialog
list.
A modal dialog to display progress of a
ProgressMonitorDialog
operation.
WizardDialog A dialog to show a wizard to the end user.
A simple input dialog for getting an input from
InputDialog
the user.
Lets try out a simple dialog example
We will modify ResourceManagerViewActionDelegate to try out some dialogs. Here is new code listing.
package com.myplugin.rmp;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.ui.IViewActionDelegate;
import org.eclipse.ui.IViewPart;
If you use Eclipse IDE for java development then you must have used Wizards extensively for
example, while creating Java class or while new Projects etc.
Wizards are helpful in performing repetitive tasks for ex: New Java Class wizard takes information
from user and create java class template. Depending upon user input it is also generate main method,
abstract methods from super class etc.
Open Resource Manager plugin project and create a new java class as described in steps below:
2. Create a new Wizard Page (PersonalInformationPage) by creating java class as shown in figure
below
Figure 6-3
package com.myplugin.rmp.wizards;
import org.eclipse.jface.wizard.WizardPage;
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;
public class PersonalInformationPage extends WizardPage {
Text firstNameText;
Text secondNameText;
protected PersonalInformationPage(String pageName) {
super(pageName);
setTitle("Personal Information");
setDescription("Please enter your personal
information");
}
public void createControl(Composite parent) {
Composite composite = new Composite(parent,
SWT.NONE);
GridLayout layout = new GridLayout();
layout.numColumns = 2;
composite.setLayout(layout);
setControl(composite);
new Label(composite,SWT.NONE).setText("First
Name");
firstNameText = new Text(composite,SWT.NONE);
new Label(composite,SWT.NONE).setText("Last
Name");
secondNameText = new Text(composite,SWT.NONE);
}
}
package com.myplugin.rmp.wizards;
import org.eclipse.jface.wizard.WizardPage;
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;
Figure 6-4
package com.myplugin.rmp.wizards;
import org.eclipse.jface.wizard.Wizard;
public class CaptureEmployeeInfomrationWizard extends Wizard {
PersonalInformationPage personalInfoPage;
AddressInformationPage addressInfoPage;
From Overview tab of Manifest editor - launch eclipse to test your changes. Open Resource Manager
Perspective and click on toolbar action to open up wizard (See image below).
Figure 6-5
ECLIPSE VIEWS
In eclipse the entire workbench contains one or more workbench windows. Each workbench window
may further contain one or more workbench pages and each page may contain one or more editor or
views. An editor is typically used to edit/modify a workspace resource whereas Views are arranged
around editors and provide assistance to editors in some way (though this is not always true). Views
are used to display hierarchy of information, open up an editor or display properties for an active
editor. Classic example of view is Package explorer and outline view. Package explorer is used to
display workspace resources in a hierarchy and is used to open up associated editor whenever user
performs double click action on the resource. Outline view is used to display information about the
java resource for ex: package declaration, imports etc. (See figure below)
One of the key difference between editors and view is that editors are resource based i.e. they work
on underlying resources in workspace. For ex: XML editor requires “.xml” file in workspace. Whereas,
views may not be resource based. They can be used to show any kind of information. It is also
important that we can make views which may display information irrespective of resources opened up
in editor window (that’s why I said its not always true that view plays role of assistant window around
editor area).
In this chapter, we will create Property File Manager View so that it does something useful and more
meaningful rather then just displaying static data.
Property File Manager View will search the entire workspace for all the projects. In each project it will
search for "Property Files" folder, In each such folder it will look out for all the files with
".properties" extension and display it to the user. This way we will end up with a view as shown in
the figure below. Please note that a property file gets displayed in the Property File Manager view only
when it is created inside Property Files folder.
Property File Manager View
In order to create a new view, open up manifest editor – click on extensions tab. Right click on
“org.eclipse.ui.views” extension and click on new > view (See figure below)
It will immediately open up Extension element details page. Edit the element details as shown below
In order to create “com.myplugin.rmp.views.PropertyManagerView” class click on the class link to
open up Java attribute editor as shown below:
Click finish to generate the Property Manager View class.
What follows is the complete listing of Property Manager View class. However, before we move ahead
to show this listing we will need to add two dependencies (if not already added) in the plug-in
manifest editor.
Second dependency (org.eclipse.ui.ide) is required since we will open up associated editor whenever
user clicks on listed property files in property manager view.
In order to add the dependencies, open up manifest editor – click on dependencies tab and add above
two dependencies as shown in fig below:
Once the dependencies have been added following code listing will compile successfully.
1. package com.myplugin.rmp.views;
2. import java.util.ArrayList;
3. import org.eclipse.core.resources.IFile;
4. import org.eclipse.core.resources.IFolder;
5. import org.eclipse.core.resources.IProject;
6. import org.eclipse.core.resources.IResource;
7. import org.eclipse.core.resources.IWorkspace;
8. import org.eclipse.core.resources.ResourcesPlugin;
9. import org.eclipse.core.runtime.IAdaptable;
10. import org.eclipse.jface.action.Action;
11. import org.eclipse.jface.action.MenuManager;
12. import org.eclipse.jface.dialogs.MessageDialog;
13. import org.eclipse.jface.viewers.DoubleClickEvent;
14. import org.eclipse.jface.viewers.IDoubleClickListener;
15. import org.eclipse.jface.viewers.ISelection;
16. import org.eclipse.jface.viewers.IStructuredContentProvider;
17. import org.eclipse.jface.viewers.IStructuredSelection;
18. import org.eclipse.jface.viewers.ITreeContentProvider;
19. import org.eclipse.jface.viewers.LabelProvider;
20. import org.eclipse.jface.viewers.TreeViewer;
21. import org.eclipse.jface.viewers.Viewer;
22. import org.eclipse.swt.SWT;
23. import org.eclipse.swt.graphics.Image;
24. import org.eclipse.swt.widgets.Composite;
25. import org.eclipse.swt.widgets.Menu;
26. import org.eclipse.ui.ISharedImages;
27. import org.eclipse.ui.IWorkbenchPage;
28. import org.eclipse.ui.PlatformUI;
29. import org.eclipse.ui.ide.IDE;
30. import org.eclipse.ui.part.ViewPart;
83. }
84. class ViewContentProvider implements ITreeContentProvider {
114. }
125. }
getFile(tempObj.getResouce().getFullPath());
174. IWorkbenchPage dpage =
PropertyManagerView.this.g
etViewSite()
.getWorkbenchWindow().getActivePage();
175. if (dpage != null) {
176. try {
177. IDE.openEditor(dpage,
ifile,true);
178. }catch (Exception e) {
179. // log exception
180. }
181. }
182. }
183. };
184. });
185. }
You might face issues understanding above code if you have not gone through JFace Viewers chapter.
I would briefly discuss main points of complete listing below – for detailed information on SWT/JFace
viewers please read respective chapters.
Lines 32 - 125: Nothing special here - Most of the SWT/JFace concepts have been put to practice.
TreeObject and TreeParent represents the model objects for our TreeViewer class. We have used
TreeViewer class here because we need to show property files under “WorkSpace Property Files”
folder, so it is more like tree rather then a table.
TreeParent represent Folders whereas TreeObject represent Files in specific folder. These two classes
are essentially wrappers/adapters over the IResource objects. In our example we will use TreeParent
to represent “WorkSpace Property Files” folder and TreeObject to represent various property files.
ViewContentProvider: A content provider is another common adapter type used in viewers. This
provider is used to map a domain model object used as the input to the viewer and the internal
structure needed by the viewer itself. We have implemented ITreeContentProvider interface. This
interface adds support for retrieving an item's parent or children within a tree. Special attention is
required for the method.
93. return
getChildren(invisibleRoot);
94. }
This method returns the elements to display in the viewer. This method is called internally by the
viewer and reference to the parent object is passed as an argument. In line 90, we are comparing
parent with the ViewSite returned by getViewSite() method. Views are contained in a view site
(org.eclipse.ui.IViewSite) and ViewSite is in turn contained in a workbench page
(org.eclipse.ui.IWorkbenchPage). Basically at this time we want to know whether the elements are
demanded by View itself or TreeParent object(folder). If it is demanded by View itself then we will
initialize our model object and return it to viewer.
ViewLabelProvider: This provider is used to map a domain model object into one or more images and
text strings displayable in the viewer's widget. We will use this provider to display names of property
files as well as folder. Also, we have used this provider to display images in the view.
Line 127: We have created TreeParent to represent “WorkSpace Property Files” folder which will
act as a parent folder for all property files in workspace.
Line 129: he handle of workspace through Resources plug-in. Resource plugin is used for any
workspace/resource modifications problems.
Line 130: workspace.getRoot() returns the root resource of this workspace. It is basically container of
all projects in the workspace. IWorkspaceRoot.getProjects() returns the collection of projects which
exist under this root. The projects can be open or closed.
.getName());
141.
obj.setResouce(fileResources[k]);
142.
root.addChild(obj);
143. }
144. }
145. }
146. }
147. }
148. }
149. }catch (Exception e) {
// log exception
150. }
151. invisibleRoot = new TreeParent("");
152. invisibleRoot.addChild(root);
153. }
Line 131 – 151: Here we are iterating over projects in a workspace. For each project we are looking
for folder named “Property Files”. In this folder we are looking for files with extension “.properties”
and if they exist we create our domain model TreeObject and add this object to TreeParent created
above by using root.addChild(obj) method. Following figure shows the hierarchy of IResource
interface. For complete API listing refer Eclipse Platform Documentation.
Lines 151 - 152. Basically we have created an invisible node (TreeParent) which will act as a root
node of tree but it will not be visible to user. This node will also act as a parent node for all the folders
in the tree. We are adding root node which represents “Workspace Property Files” folder as child to
invisible node.
Lines 156 – 163: we are overriding createPartControl (Composite) method defined in WorkbenchPart
Class. This method is responsible for creating SWT/Jface components for our properties view. In this
method we are creating TreeViewer and providing content , label providers to the viewer. For more
information on this refer to Jface viewer chapter. Viewer.setInput method is used to provide the initial
input to the viewer. We have used getViewSite method to get site reference which is passed to viewer
as initial input. That is the reason that we are checking for parent.equals(viewsite) at line 90. We
could have very well used invisibleroot in setinput method instead. Point is that our domain model
gets to meet viewer control with the help of setInput method.
Next we have called to methods to provide context menu and doubleclick action to our property view.
.getWorkbenchWindow().getActivePage();
175. if (dpage != null) {
176. try {
177.
IDE.openEditor(dpage, ifile,true);
178. }catch (Exception e) {
179. // log exception
180. }
181. }
182. }
183. };
184. });
185. }
On line 168, we are retrieving first element from the structured selection. Next we are checking if
current selection is a property file by comparing it to TreeObject. Remember that TreeObject is our
domain model which we have created in the initialize method and it represents the property file. Next
we are retrieving Ifile handle with the help of TreeObject. Remember TreeObject saves the instance of
corresponding Resource Object. On line 177, we are opening up the editor with the help of
IDE.openEditor method.
The above method opens the editor for the given file resource. This method will attempt to resolve the
editor based on content-type bindings as well as traditional name/extension bindings. * If the page
already has an editor open on the target object then that editor is brought to front; otherwise, a new
editor is opened. If activate == true the editor will be activated.
Lines 186 – 198 : Nothing special here, your knowledge about actions have been put to practice
here. Essentially we have created new action which will perform viewer.refresh() – This will refresh
the tree starting from invisible node. We can also use public void refresh (final Object element)
to perform refresh action on a particular folder by passing TreeParent object.
Lines 199 – 201: We have overridden setFocus method defined in WorkbechPart class. This method
asks view to take focus within the workbench.
Testing the modifications you have just made involves launching the Runtime Workbench. Open up
Property Manager View (Window > ShowView > Other)
It will open up Property Manager View as shown below.
Next, create a new project as shown below
Click Next, Name it Testing and click finish
Now create a new Folder inside the project
Make sure that you name this folder “Property Files”
Next, create some property files inside the Property Files Folder
Make sure that you provide right extension for these files:
Once you have created a property file, Right click on WorkSpace Property Files Folder in the property
manager view and click refresh.
You will notice that newly created file(s) is listed in property view as shown in figure below.
ECLIPSE TRACKING CHANGES
In Last chapter (Views) we created a property manager view. Whenever user click refresh action, this
view searches for all the property files in the workspace and displays it to the user. Wouldn’t it be cool
if this view can refresh automatically whenever a property file is added to workspace? If you answer
yes, then you are at right place.
Eclipse provides IResourceChangeListener to keep track of resource changes in the workspace. Eclipse
generates resource change events indicating that the files and folders that have been added, modified,
and removed from the workspace. Interested parties can subscribe to these events and take
necessary action. The interface org.eclipse.core.resources.IResourceChangeListener defines single
method:
public void resourceChanged (IResourceChangeEvent event). In this chapter we will modify
PropertyManagerView so as to implement IResourceChangeListener and use IResourceChangeEvent to
update itself. Before we move on it is important to understand IResourceChangeEvent.
According to Eclipse API Specification there are currently five different types of resource change
events:
• PRE_BUILD
• POST_BUILD
• POST_CHANGE
• PRE_CLOSE
• PRE_DELETE
Please refer to online Eclipse API Specification to know more about these events.
A resource delta represents changes in the state of a resource tree between two discrete points in
time OR we can say it is through delta object that we come to know about the changes taking place in
workspace. Whenever resource modification is performed by the user delta of modification is prepared
by eclipse and interested parties can use this delta to update themselves. This interface declares many
constants describing the kind of change.
Please refer to online Eclipse API Specification to know about methods provided by IResourceDelta.
Best way to learn above mentioned theory is to practice with concrete example. In this section we will
take step by step approach to
modify Property Manager View so that it can keep itself updated with resource modifications in
workspace. Lets start by implementing IResourceChangeListener. Open
com.myplugin.rmp.views.PropertyManagerView in java editor and implement resource change listener
as shown below.
Next, register PropertyManagerView with Work Space so that this view is notified whenever work
space modification event is generated.
Modify createPartControl method as shown below:
Next, Override dispose method of view to remove Listener. Dispose method of View is called every
time the View Part is destroyed.
Line 3: We are only interested in Post change events. So here we are checking the event type. If the
event is a POST_CHANGE event then we proceed ahead.
Line 4: getDelta() method in IResourceChangeEvent returns the delta i.e. information about the
modifications which triggered this event.
Line 5: IResourceDeltaVisitor is an object that visits (visitor pattern) resource deltas. It visits resource
deltas that are ADDED, CHANGED, or REMOVED. In case visitor returns true - the resource delta's
children are also visited.
Line 6: Here we are retrieving the resource which has been modified and checking if it is a .properties
file.
Line 7: If the modified resource is a .properties file then we are initializing our model object again.
Line 8 – 13: Next we want to refresh viewer so that it updates itself and resource changes are visible
in Property Manager View. The code Display.getDefault().asyncExec(new Runnable(){… makes sure
that we don’t get illegal thread access exception. If we try to refresh viewer outside of this code (say
immediately after initialize is called) then we will get illegal thread access exception. Reason? Basically
the resourceChanged Method is called in a non UI thread and when we try to modify UI by calling
viewer.refresh() in this non UI thread it throws exception. In order to overcome this problem we have
redirected the execution to UI Thread by using Display object.
Launch eclipse application from plug-in manifest editor. Open up Property manager View (Window >
show view > other). Create property files in Project under folder (Property Files) and notice that
Property manager View Refreshes on every addition/deletion of property file resource.
GETTING STARTED WITH PREFERENCE PAGES
Preference Pages
As an eclipse user you must have used preferences on many occasions. A Preference is a data which is
persisted between workspace sessions.
Preferences are used in Eclipse to take preferences from user on the fly rather then hard cording them
in plug-in itself. In order to view preferences go to window > preferences. Following figure show how
preferences dialog look like.
In this chapter we will create a new preference page which will take Folder name preference from
user. This folder name will be used in Properties view instead of hard coding “Workspace Property
Files”.
Property File Manager Preference Page
Eclipse provide a wizard for creating preference pages. Open plugin.xml. Navigate to the Extensions
page followed by clicking "Add" button then click on org.eclipse.ui.preferencePages. Now select
Preference Page in list of available templates as shown below.
Click next button and provide values as shown in figure below and click finish.
After you click finish, open up com.myplugin.rmp.preferences.PropertyManagerPreferencePage class to
see the default implementation. We will discuss default implementation in sections to follow. At this
time we will launch new runtime workbench to see how Property Manager Preference page looks like.
Once you launch new Runtime workbench, open preference dialog (Window > preferences) and you
will see something as shown in figure below.
Note about FieldEditor and FieldEditorPreferencePage
Field editors are basically used to make UI of a preference page. A field editor can be thought of as an
item which is used to show the user with the value of a preference. FieldEditor is mostly used together
with a FieldEditorPreferencePage, Eclipse provides many ready-to-use field editors as shown in figure
below.
FieldEditorPreferencePage is a special abstract preference page to host field editors. Our preference
page extends FieldEditorPreferencePage, which, along with the various editor classes helps in
capturing preferences. Following figure shows complete hierarchy of FieldEditorPreferencePage. Please
refer to Eclipse API Specification to know about methods available in this class.
Armed with the knowledge of field editors and FieldEditorPreferencePage we are now ready to review
the generated code. Open com.myplugin.rmp.preferences.PropertyManagerPreferencePage class.
Notice that the default implementation (generated by wizard) extends FieldEditorPreferencePage and
implements IWorkbenchPreferencePage interface.
24. addField(
25. new
StringFieldEditor(PreferenceConstants.P_STRING,
"A &text preference:",
getFieldEditorParent()));
26. }
27. public void init(IWorkbench workbench) {
28. }
29.}
Line 6: Sets the preference store for this preference page. We are using
RmpPlugin.getDefault().getPreferenceStore() to retrieve the preference store for this Resource
Manager Plugin. getDefault method returns the shared instance of plug-in. every plug-in has its own
preference store. Preferences are stored in a
<runtimeworkspace>\.metadata\.plugins\<pluginid>\pref_store.ini file.
Line 7: Set Description method is used to set the description title on the top of preference window.
Line 9 -26: createFieldEditors method is used to create GUI of the preference page. In this method we
are creating four field editors (Directory, Boolean, Radio and String). AddField method is used to add
the filed editor to preference page.
DirectoryFieldEditor
This editor is used to create a directory filed with in the preference page. First argument to
constructor is the name of this field. This name is defined as a constant in
com.myplugin.rmp.preferences.PreferenceConstants which was generated by preference page creation
wizard. These names are also used to retrieve values of a specific preference from preference store.
Last argument specifies the parent of the field editor's control. We are using getFieldEditorParent()
defined in FieldEditorPreferencePage to retrieve the parent control.
BooleanFieldEditor
This editor is used to create a Boolean field. It creates a checkbox in the preference page. Arguments
are same as described in directory filed editor.
RadioFieldEditor
This editor is used to create a radio button field. Third argument is the numColumns - the number of
columns for the radio button presentation.
In our case it is one. Next argument is the labelAndValues list of radio button [label, value] entries.
The value is returned when the radio button is selected
StringFieldEditor
This editor is used to create a Text box which takes a String as input. Arguments are same as
described in DirectoryFieldEditor.
Lines 27 – 28: We have not used this method. However, it can be used to Initialize this preference
page for the given workbench.
In this section we will modify the preference page so as to create a single String Text Box where user
can set his preference for the name of folder which will be displayed in the Property Manager View.
Modify the PreferenceConstants class to add another constant FOLDER_NAME as shown in bold below.
Following figure shows, how preference page will look like after above customization.
The FieldEditorPropertyPage listens for FieldEditor.IS_VALID property change events and then calls
checkState() and setValid() as necessary. The String field editors are never in an invalid state and
thus do not issue FieldEditor.IS_VALID property change events, only FieldEditor.VALUE property
change events. You must override the FieldEditorPreferencePage propertyChange() method to call the
checkState() method when the FieldEditor.VALUE property change event is received.
With above change an error message is displayed across the top of the preference page and the Apply
and OK buttons are disabled (as shown below)
Next, Modify com.myplugin.rmp.preferences. PreferenceInitializer (Generated by create preference
page wizard) to set the default value for folder name. In general Initializers are used to initialize
default preference values. Modify initializeDefaultPreferences() as shown below
With above change, folder name will be defaulted to “WorkSpace Property Files” whenever user clicks
on default button in preferences dialog (as shown below)
Next Modify PropertyManagerView class so as to use preference rather than hard coded folder name.
Modify initialize method as follows:
String folderName =
store.getString(PreferenceConstants.FOLDER_NAME);
IProject[] projects =
workspace.getRoot().getProjects();
rest method is same
With above mentioned change, On every refresh on root node of Properties view – folder name will be
picked up from preferences.
GETTING STARTED WITH PROPERTIES
Eclipse plugin Properties are used to assign additional information to resources and objects.
Additional information could be anything. For Example, we may want to attach author name property
with the java file resource in eclipse. There are two ways to access resource property. First, right click
on resource and select properties option from context menu (as shown in figure below)
Another way to access properties for a resource is to open up the properties view from Window >
Show View > Properties (as shown in figure below)
In this chapter we will learn how to create property on a particular resource and display it's properties
in properties dialog as well as properties view. For the purpose of our example we will associate
properties with property files displayed in Property Manager View. We will create a context menu
option to open properties dialog. Later on we will see how to display properties in property view when
ever user selects a property file in Property Manager View.
We will first create a property page through plug-in manifest editor. This preference page will be
shown in properties dialog. In order to create property page open plugin.xml in manifest editor.
Navigate to extension page. Click on Add… button. Select org.eclipse.ui.propertyPages and click finish.
Next, In the extensions page right click on org.eclipse.ui.propertyPages and select new > page. Click
on new page declaration and edit its properties as shown in figure below. We need to provide
TreeObject class in object Class because we will be showing property dialog on selection of property
files in Property Manager View and model class for property files in our view is TreeObject class.
Note: In order to access TreeObject class in below mentioned properties change access modifier from
default to public. Also change the getResource() method in TreeObject to public from protected. It will
be accessed from outside in coming sections.
Next, generate the com.myplugin.rmp.propertyPage class by clicking on class link in manifest
editor(extensions page) with the help of java attribute dialog. Modify the
com.myplugin.rmp.propertyPage as shown in the listing below.
1. package com.myplugin.rmp;
2. import org.eclipse.core.resources.IResource;
3. import org.eclipse.core.runtime.CoreException;
4. import org.eclipse.core.runtime.QualifiedName;
5. import org.eclipse.swt.SWT;
6. import org.eclipse.swt.layout.GridData;
7. import org.eclipse.swt.layout.GridLayout;
8. import org.eclipse.swt.widgets.Composite;
9. import org.eclipse.swt.widgets.Control;
10. import org.eclipse.swt.widgets.Label;
11. import org.eclipse.swt.widgets.Text;
12. import org.eclipse.ui.IWorkbenchPropertyPage;
13. import org.eclipse.ui.dialogs.PropertyPage;
14. import com.myplugin.rmp.views.PropertyManagerView.TreeObject;
Lines 15 -16: We are extending abstract base class PropertyPage. This class is Abstract base
implementation of a workbench property page (IWorkbenchPropertyPage). Subclasses of this base
class should implement the createContents method in order to provide the property page's main
control. Following figure shows the hierarchy of this class.
Lines 22 – 35: Here we are implementing createContents method defined in PreferencePage class.
This method creates and returns the SWT control. Nothing special here we are just using SWT controls
to create the GUI of properties dialog. At line 33 we are calling getAuthor() method discussed next to
get the existing author property.
Lines 37 - 38: In our properties dialog we will be showing single property named author for every
“.properties” file. getAuthor() method is used to fetch the existing property saved in workspace.
getElement() returns the object that owns the properties shown in the dialog. In our example case
this dialog will open up whenever user right clicks on “.property” file in Property Manager View. Since
our model object behind tree viewer is TreeObject we are casting getElement with TreeObject. Finally
we are fetching corresponding resource object from treeObject.
Lines 39 – 50: There are two types of properties: persistent and session. Methods in IResource
provide both session properties, which are discarded when Eclipse exits, and persistent properties,
which are preserved across multiple workspace sessions. Following are the four methods provided by
IResource implementation
getPersistentProperty(QualifiedName)
getSessionProperty(QualifiedName)
setPersistentProperty(QualifiedName, String)
setSessionProperty(QualifiedName, Object)
Lines 51 – 64: All concepts are similar to what we discussed above with exception that we are using
setPersistentProperty to set the author property for every object.
Lines 65 – 68: finally we are overriding perform ok method to fetch author name from dialog and
calling the setAuthor() method which will persist the preference.
Property descriptors objects are used to create a property editor in the Properties view. Eclipse
provides some implementations of the IPropertyDescriptor interface as shown in figure below.
If you are not able to understand above mentioned details then don’t worry!! What follows is the step
by step approach of integrating properties View with our own Property Manager View (similar names!!
Don’t get confused, Property Manager View is our example view where in we are displaying all the
property files in workspace whereas Properties View is provided by eclipse to display properties of
object selected in workbench).
TextPropertyDescriptor(AUTHOR_ID,"author");
private static final IPropertyDescriptor[] DESCRIPTORS =
{ AUTHOR_PROP_DESC };
Next, modify com.myplugin.rmp.views.PropertyManagerView$TreeObject as shown below (notice
changes in bold):
public class TreeObject implements IAdaptable,IPropertySource {
private String name;
private TreeParent parent;
private IResource resouce;
}
return null;
}
}
}
}
Now, whenever a “.properties” file is selected in Property Manager View. Its properties are shown in
Eclipse Properties View as shown in figure below.
ECLIPSE PLUGIN EDITORS TUTORIAL
Editors are used to create/modify workspace resources. As an Eclipse user you must have used editors
all the time. Famous example of editor is the Java Editor. It provides many capabilities like Content
assist, color coding and so on. There is no specific implementation of an editor because editors
essentially cater to application specific behavior.
Once the implementation model for an editor is determined, implementing the editor is much like
programming a standalone JFace or SWT application.
Workbench Editors
Although the implementation of a workbench editor will be specific to your plug-in and the content
that you want to edit, the workbench provides a general structure for building an editor. Editors
should implement org.eclipse.ui.IEditorPart interface. In Eclipse, Editors rests inside
org.eclipse.ui.IEditorSite, which in turn rests in org.eclipse.ui.IWorkbenchPage.
Thankfully, Eclipse provides two important base implementations of IEditorPart interface namely
EditorPart and MultiPageEditorPart (discussed next). Major difference between the two type of editors
is that MultiPageEditorPart provides the functionality of displaying multiple pages on same editor in
tabbed fashion – similar to what we see in plug-in manifest editor (Overview tab, extensions tab,
dependency tab etc.)
EditorPart
This is the Abstract base implementation of all workbench editors. Subclasses must implement the
following methods:
MultiPageEditorPart
A multi-page editor is an editor with multiple pages, each of which may contain an editor or an
arbitrary SWT control. Subclasses must implement the following methods:
• CreatePages - to create the required pages by calling one of the addPage methods (pages will
be subclasses of EditorPart discussed above)
• IEditorPart.doSave - to save contents of editor
• IEditorPart.doSaveAs - to save contents of editor
• IEditorPart.isSaveAsAllowed - to enable Save As
• IEditorPart.gotoMarker - to scroll to a marker.
Creating Editor by using inbuilt editor template
In order to understand editor concepts we will use one of the templates available in eclipse itself. This
template creates a multi-page editor. The editor has three pages: Edit where you enter text,
Properties that allows you to change font of the result and Preview that shows sorted words from the
Edit page using the font set in Properties.
In order to create multi-page editor, open plug-in.xml file. Navigate to extensions tab and click on
Add. Select “Extension Wizards” tab followed by Multi-page Editor as shown in figure below.
Editor Class Name: is the name of multi page editor class which will be generated after this wizard
finishes
File Extension: This attribute specifies the file extensions with which we would like to associate this
particular editor.
Next, Click finish. Save the Plugin manifest file. We will first look how newly created editor looks like
before reviewing the generated code. In order to view the editor in action launch eclipse runtime
application. Create a new file from right click context menu as shown below:
Name the new file anything but keep the extension of the “.mpe” because this is the extension with
which newly created editor is associated with. Once you have created the file – Sample Multi-Page
editor will open up with three tabs namely <filename>.mpe, Properties and Preview. Play around with
the editor before we get onto reviewing generated code.
Let’s Review the generated code
Extensions: every editor typically understands only special file extensions. For ex: XML editor
understands only .xml extension. You can provide file extensions (comma separated) understood by
editor.
Command: We can specify command here to launch an external editor. For example: I may like to
open XML SPY (external editor) when user clicks on xml file inside eclipse.
Default: If true, this editor will be used as the default editor for the file extension
As discussed earlier that implementation of editor is much like programming a standalone JFace or
SWT application. So we will not get into details of how to build an editor with help of SWT/JFACE. We
will just concentrate on the lifecycle of editor. In Coming sections ill discuss various editor specific
methods. We will discuss the order in which these method get called (in editor lifecycle) and what is
the purpose of these methods.
public MultiPageEditor() {
super();
ResourcesPlugin.getWorkspace().addResourceChangeListener(this);
}
Whenever user clicks on a “.mpe” file constructor of MultiPageEditor will be called. This class
implements IResourceChangeListener (discussed in resource change tracking chapter). In editor
constructor we are registering this instance of editor with the workspace so that editor is notified for
any resource changes in the workspace.
Next in the editor lifecycle init method is called, we are overriding init method defined in EditorPart
class. This method is the first method to be called when editor is created In this method we are
verifying whether the editor input is acceptable (it should be instance of IFileEditorInput) otherwise
throwing an exception. IEditorInput is a light weight descriptor of editor input, like a file name but
more abstract. It is a object which can be queried to know more about the input which is coming to
editor.
void createPage0() {
try {
editor = new TextEditor();
int index = addPage(editor, getEditorInput());
setPageText(index, editor.getTitle());
} catch (PartInitException e) {
ErrorDialog.openError(
getSite().getShell(),
"Error creating nested text editor",
null,
e.getStatus());
}
}
...
...
Next in the editor lifecycle createPages() method is called, This method creates the pages of this
multipage editor. Typically, this method simply calls more finely grained methods such as
createPage0(To create eclipse plugin text editor), createPage1(To create composite) etc. So this
method is used to create the GUI for our editor. Next, in createPage0() we are creating a new
TextEditor. This is a inbuilt standard text editor for file resources (we could have created our own
editor by extensing EditoPart Directly). addPage method is used to add a new page containing the
given editor to this multipage editor. addPage returns the index where this page is added. Next
setPageText is used to set the title for the page index.
isSaveAsAllowed() returns whether the "Save As" operation is supported by this editor part. This
method calculates whether save action should be disabled or enabled whenever editor is opened.
pageChange(int) method is called whenever user toggles the page tab on bottom of multi page editor.
This method is used to calculate the contents of selected page.
doSave() and doSaveAs() methods are called whenever user clicks “Save” or “Save As” actions. We
are using editor at index zero i.e. the Text Editor to save the file. On save, the editor should generate
a property changed event (PROP_DIRTY). doSaveAs() is used to open a Save As dialog
gotoMarker() sets the cursor and selection state for this editor as specified by the given marker. We
will discuss about markers in chapters to follow.
In above example we have not covered process to mark editors dirty so that Save and Save As
buttons can be enabled. Whenever user makes some modification to editor file we can mark editor as
dirty by calling firePropertyChange(IEditorPart.PROP_DIRTY). We can also use isDirty() method to see
if editor is marked as dirty at any point in editor.
This class is responsible for Managing the installation/deinstallation of global actions for multi-page
editors. In our example editor, you will notice that “Editor Menu” action is displayed on top menu
whenever editor is opened (as shown in figure below). This action is removed from workbench menu
bar whenever multi page editor is closed.
getActionBars() : it returns the contributor's action bars provided to the contributor when it was
initialized.
getPage(): it returns the contributor's workbench page provided to the contributor when it was
initialized.
contributeToMenu(): Contributes to the given menu. In our example we are adding new “Editor
&Menu” to the workbench menu.
setActivePage(IEditorPart part): This method is called whenever the page changes. This method
Sets the active page of the multipage editor to the given editor. If there is no active page, or if the
active page does not have a corresponding editor, the argument is null. We are calling
Builders: If you are using Eclipse IDE for java development then you are not new to Builders. Inside
Eclipse builders are used to take java source as input and generate corresponding class files. So you
can define builders as an engine which generates some output based on your input. Incremental
Builders - These contribute to performance improvement by rebuilding only the delta since last full
build.
Markers: Markers are used mark locations in editor. Java editor uses these markers to mark error
locations, warnings, book marks etc.
Natures: Natures are used to link project with various functionalities such as builders in a project. For
ex: if we add java nature to a project inside eclipse. It associates project with incremental java
compiler.
In order to understand builder nature and marker concepts we will use one of the templates available
in eclipse itself. This template will create an builder (incremental). In addition, it will also create a
project nature. Name of this builder is "sample builder" and it basically validates XML file and if
required adds a problem marker to problematic xml files. The builder will run only for projects which
have declared themselves as having sample nature projects. Select Add/Remove Sample Nature
action from a project context menu, to toggle the nature on a project.
In order to create project builder and nature, open plug-in manifest editor. Navigate to extensions
page followed by clicking on "Add" button. Now select Extension Wizards tab followed by Project
Builder and nature template as shown in figure below.
Click next and use default values as shown below.
Click finish and save the plug-in manifest file. Before we move onto discuss the generated code let’s
first see the builder in action. Launch eclipse runtime application. Create a new xml file in existing
project (create new project if workspace is new). Edit newly created xml file such that it is not well
formed. Right click on project and click Add/Remove sample Nature. Notice that the marker will
appear inside the editor (as shown in figure below).
Eclipse Builders
Let’s review the plug-in manifest file to see what it takes to create a new project builder.
New builder is created by extending the org.eclipse.core.resources.builders extension point. ID and
name are used to give builder a datavalue and name respectively. Point is nothing but the extension
point which we have extended.
Next, is the builder element. The hasNature attribute flags whether this builder is associated with any
nature.
Next, is the run element (class attribute). Here we specify the actual java class which provides the
functionality of the builder.
IncrementalProjectBuilder
Please refer to Eclipse API Specification to find details of all the methods provided by this Class.
The build method requires special attention here. This method of the builder is called whenever build
is required (for ex: user saves java file and automatic build preference is checked)
kind: What kind of build is required?? Kind parameter could be a FULL_BUILD, INCREMENTAL_BUILD,
and AUTO_BUILD.
Args: A map to pass arguments/information to builder.
In both of above methods we are delegating calls to Visitors. Visitor will visit all the resources (in case
of delta only the modified resources since last build). For each resource we are calling checkXML()
method. CheckXML method essentially delegates call to XMLErrorHandler defined in builder class
which will check if XML document is well formed or not. In case it is not well formed it will create a
marker (as shown below). I am not going into details of SAX parsing or SAX event handlers (it is out
of scope for this tutorial). We are using Sample builder’s addMarker method to create a marker on line
number where the exception occurred.
Markers
As described earlier, Markers are used mark locations in editor. Java editor uses these markers to
mark error locations, warnings, book marks etc.
There are many types of predefined markers defined as constants in IMarker interface.
org.eclipse.core.resources.bookmarkIMarker.BOOKMARK
org.eclipse.core.resources.markerIMarker.MARKER
org.eclipse.core.resources.problemmarker IMarker.PROBLEM
org.eclipse.core.resources.taskmarkerIMarker.TASK
org.eclipse.core.resources.textmarkerIMarker.TEXT
Let’s review the plug-in manifest file to see what it takes to create a new marker. New marker is
created by extending org.eclipse.core.resources.markers extension point. ID and Name are datavalue
and name respectively. Point is nothing but the extension point we are using to create this marker.
Next, we need to define the super type marker for new marker. Since we want to show errors in
Problems View we are using org.eclipse.core.resources.problemmarker as supertype.
Next is the persistent element. Since we want this markers to persist across eclipse sessions we are
setting this property to true.
Reviewing the generated code
addMarker method in SampleBuilder class is used to show above defined marker in the editor
whenever problem/error occurs.
Natures
Natures are used to link project with various functionalities such as builders in a project. For ex: if we
add java nature to a project inside eclipse. It associates project with incremental java compiler.
natures are added in .project file of the project. Natures are not only used to associate builders but
are also used to define many other functionalities for ex: only java nature projects are shown in
Package Explorer. Some of the predefined natures are
org.eclipse.jdt.core.javanature,org.eclipse.pde.PluginNature
Let’s review the plug-in manifest file to see what it takes to create a nature. Nature is created by
extending org.eclipse.core.resources.natures extension point. ID is the unique identifier for this
nature. Name is the human readable name of the nature.
Next element is the builder. Here we will add a builder to this nature. We have associated
SampleBuilder created earlier with this nature. So that projects with SampleNature use SampleBuilder
whenever an XML file is saved.
Next elements which we are going to discuss are runtime and run. Here we will specify a class named
Sample Nature which will be used to configure/deconfigure project with Sample Nature. With the help
of this class we will be able to configure non Sample Nature project to Sample Nature project at run
time. OR we will be able to convert Sample Nature Project to non Sample Nature project.
Repercussions of making a Project as Sample Nature project will be that a Sample builder will be
attached to project which will run whenever an XML file is saved and will look for any errors in XML.
IProjectNature
In our example, user is provided with toggle action to convert non Sample Nature project to Sample
Nature project. Following method from SampleNature class will be called to associate the project with
SampleNature.
Help in eclipse is accessed by using Help > Help Contents menu. Once you done with development of
your plug-in and before you are ready to ship it as a product, one thing which you would like to do is
create help contents. No matter how simple or complex your plugin is, users would like to see get
started documents. Also help provide us with opportunity to describe functionalities available with the
plugin.
Creating New Help
Eclipse has support for many formats like HTML, PDF, XHTML to name a few. We can create help
within the main plugin or create altogether a new plugin project for help.
We will start by creating a new Plug in project. In order to create new project click on File > New
Project > Select Plug in project (as shown below)
Click next button, Provide “com.myplugin.rmp.help” in Project Name field.
Click next button, Provide values as shown in figure below.
Click finish, this will create a new plug in project and will generate minimal code for the project. Till
this point project is empty. Now we will use Existing extension templates to generate necessary files
for creating help.
Navigate to Extensions page, click on "Add" button and select Extensions Wizard tab followed by
selecting Help Content template. This template creates a Help table of contents. If this table is set to
primary, it can be standalone, or integrated into pre-set categories. If this is not set as primary then it
can be attached with the primary toc for testing purposes.
Click Next button and provide values as shown below: Check the Primary Option. This will create a
primary table of content file. We will select only Getting Started and Reference categories for this
example.
Click Finish and save the manifest file.
Once you have finished creating the extension points you will notice that many files have been
generated by the Help Template Wizard. It also creates html files in a new folder.In order to create
eclipse help org.eclipse.help.toc extension point is used. Next, we have to create various toc’s and
mark them primary/secondary depending on the type of help we are creating. Every toc is represented
by XML file.
Now let’s have a look at toc.xml file. Remember this file represents primary table of contents file.
This is all it takes to create a help with eclipse. In order to test recently created help, launch new
eclipse runtime and open help window, you will see newly created help in the Eclipse help System.
In today’s world internationalization has become really important. Good news is that Eclipse has
internationalization support. This is achieved by externalizing strings to a resource bundle. In Eclipse
plug-in’s there are many files which can contain Strings (seen by end user) such as plugin.xml, Views,
Editors and more specifically all the GUI labels.
In this chapter (eclipse plugin for internationalization) we will externalize strings (seen by end
user) to a properties file called plugin.properties.
In plug-in manifest file we need to externalize strings, such as the names of views, name of wizards
and the labels of actions.
Externalizing strings from the plug-in manifest file very simple and straight forward. The file
plugin.properties contains all the extracted strings.
First step is to create a new properties file in plug-in project. Right click on project > select new file as
shown below. Name this file “plugin.properties”. It must be noted that the translated files for each
targeted language should be named plugin_<language>_<country>.properties, where <language>
and <country> represent the language and country.
Edit the plugin.properties file and add following line to the file:
Next, open plug-in manifest editor and replace Property Manager View name with a descriptive key
that starts with a percent (%) sign. These are the same keys that are used in the associated
plugin.properties file. The only rule is that the keys need to be unique within the plug-in.
In order to test if strings have been externalized correctly you can play around by changing Property
Manager View name and launch eclipse runtime. Note: If your changes are not reflected in the eclipse
runtime then try clean build on your project followed by launch of eclipse runtime.
Eclipse has excellent inbuilt support for externalizing Strings. These can be used in any Java Project
not necessarily plugin project. Here ill give you brief introduction on how to use this support (Please
refer to eclipse help for complete details). We will externalize strings from
com.myplugin.rmp.preferences.PropertyManagerPreferencePage class created earlier in this tutorial.
In order to externalize strings from this class, right click on Source > Externalize Strings when this
class is open in java editor.
This will open up Externalize strings wizard. You will notice that list displays all the strings from java
file.
In this wizard against each string - "Internalize" button can be used to mark the string as non-
translatable using end-of-line comment.
On the bottom of the page you can specify properties file where these strings have to be externalized.
Change it to refer to existing resource bundle file (if you already have one). Click next and you will be
displayed following message.
Click Next, Last page will show you the summary of all the changes which will take place if you click
finish. Verify your changes and press finish so that eclipse can automatically externalize strings into
resource bundle.
Once you have finished review the generated code to see how eclipse have externalized all your
strings into resource bundle.