This is my second blog about the Eclipse Commands framework, but actually the first one containing useful (I hope) information. I'm going to focus on the topic from a practical "using it in development" point of view, trying to keep the examples as simple as possible and the theory limited. For an updated outline please refer to the first blog in the series: Eclipse RCP Commands Part One.
Short history: the Commands framework has been around partially since Eclipse 3.0, maturing over the versions until it became quite useful in Eclipse 3.3. Some refinements in Eclipse 3.4 makes it even more appealing. I must admit, before Eclipse 3.3 I saw no reason for using Commands, and I stuck to using IActions and IActionDelegates, trying to work around their issues as much as possible (and falling into the rythm of the copy-and-paste anti-pattern in order to contribute an IActionDelegate to multiple places in a UI). No I'm trying to convince all my clients to "renew" their code to use Commands...
What are Commands
"A command is neither the presentation nor a particular behavior implementation; it is an abstract representation of some semantical behavior." - Marc R. Hoffmann (see Article on Eclipse Commands Framework)
That's the best quote I could find as to what a Command is. What does it boil down to? I assume (hope?) you are all familiar with the Model-View-Controller pattern, used especially when developing UI applications. By abstracting a particular piece of functionality into separate Model, View and Controller objects, the code is must less coupled, allowing more (and easier) reuse, flexibility and extensibility.
Well, the Command design is not exactly MVC, but it has the same goals in mind. It abstracts the actual business or application semantics (i.e. what is actually meant to happen from business or application functionality perspective) into this thing called a Command. Worries about how it should appear in the UI (menu contributions), or what exactly must happen on a code implementation level to execute the command (handlers) is left for later. In this way we get the same decoupling of presentation and implementation as with MVC, and thus the gain in reusability of Commands and their handlers, and increase in the flexibility and extensibility of the code, thus leading overall to code that is much easier to maintain.
Add to the above paragraph that code that is easier to maintain leads to huge development cost savings, and you'll have a convincing argument to offer to your boss for allowing you to refactor away all the old IActionDelegates.
Ok, but what to we do with Commands?
Plain and simple: we use it to implement functions that our application can perform and make it available as menu or toolbar items so the user can invoke it.
On a more practical level
That is about enough theory for one day. Let's get down to the bits and the bytes.
The Example
Firstly, I want to introduce my patent-pending idea for an application. Image this: you have this cross-platform application (obviously implemented using Eclipse RCP) that can actually read electronic versions of books, that we can call "e-books". "Wow!" you say. "Amazing". "What a novel idea".
Let us call our bleeding edge application MyReader. You can download the source code for this blog's version of the example.
Step 1: Create a RCP application using Eclipse 3.4 (I'm using 3.4.1) and the New Plug-in Project wizard.
Now we have the example application that we are going to enable with Commands. Exciting, isn't it?
How to define a Command
To have a command that is actually accessible in the UI, and able to do something, we need 3 "components":
Declaring the Command (Intent)
We declare the Command using the org.eclipse.ui.commands extension point. I'm sure you remember this command we declare indicates the meaning or intent of the functionality we want to add to our application or plugin.
Let us explore this Command declaration in our example, and then I'll discuss what is going on.
We need to open an ebook file with our application, so we will define a command to do this.
Step 2: Add the org.eclipse.ui.commands extension to our plugin.xml
Steps 2 and 3 updates the plugin.xml file of the plugin project by adding the necessary extension point and declaring a basic command. The plugin.xml file now contains:
|
Congratulations! Your first command.
"But if I run my app, I don't see this command. What's wrong?" Nothing. We still need to define how this command will be visible in the UI, and what the behavior should be when this command is invoked. As mentioned earlier, these are decoupled from the Command declaration.
However, let us first examine the declaration in the plugin.xml. The org.eclipse.ui.commands extension allows us to declare, among other things, a Command. The Command definition needs the following attributes:
| id | a unique id that will be used for referring to this command when declaring the UI contributions and Handlers |
| name | a user-readable name that will be used for the label in the menu contribution(s), if the menu contribution does not define its own label |
| description | a user-readable name that will be used for the tooltip in the menu contribution(s), if the contribution does not define its own description |
We are still going to have a look at some of the other attributes available. If you can't wait, go and see org.eclipse.ui.commands for more detailed information about the extension point definition. Go on, don't mind me.
Note: here we had a look at how to declare commands using the extension point in the plugin.xml file. In a later blog I plan to discuss how to do it programmatically. I will update this section with a link to that blog as soon as it is available.
Basic menu contribution (Presentation)
It is time to get his command to be presented in the UI of the application. I assume you have already done some nice UI design work sessions with your potential end-users and you are ready to build the ultimate user friendly intuitive graphical user interface for your application. For our example we are just going to use the UI-design-by-coincidence approach and just add our stuff and see how it looks.
In order to contribute an item that will invoke a Command to the UI, we need to add the org.eclipse.ui.menus extension to our plugin.xml, and declare a MenuContribution element followed by a Command element.
We first declare where (i.e. the main menubar or toolbar, or a view or editor specific menu and/or toolbar, or a context menu) the command should be added via the MenuContribution. Then we declare the visual representation of our Command using the MenuContribution's Command element.
I'm sure you are eager to run your MyReader app now. Go ahead, please. Do you see it? A grayed-out Open eBook menu-item just underneath Exit in the File menu.
That is not quite what we intended. We'll get there, though. First a discussion on what we actually did.
We first needed to add the org.eclipse.ui.menus extension to our plugin, and then we declared that we want to contribute an item to a menu via the MenuContribution element. We only had to specify one attribute: the locationURI. More on that in the next section.
We then declared that we are actually contributing a Command item as part of our MenuContribution. This is not the actual definition of a Command, but just an element indicating that we wish to represent the command with the identifier specified in commandId as an item in the menu or toolbar that we are declaring this MenuContribution for. Thus by specifying the locationURI "menu:file?after=additions" and the commandId "com.richclientgui.myreader.commands.OpenEBook" we are saying that we want the OpenEBook command to display in the standard File menu after the additions placeholder.
The mnemonic attribute indicates what character should be underlined and act as a shortcut key for selecting the menu item, if that menu is currently open. Other additional attributes can be specified to manage the presentation of the Command in the menu, e.g. the icon, label (overriding the value set in the Command's name attribute), tooltip (overriding the value set in the Command's description attribute), etc. This gives us the flexibility to present the same Command slightly different depending on where it gets contributed, something that is not possible with IActions and IActionDelegates.
LocationURI
The locationURI is an interesting attribute: it allows the developer to use a URI string to specify where a specific contribution (whether it is a command item, a submenu or some other widget that can be contributed) must be added. It is of the form:
[scheme]:[id]?[placement arguments]
| scheme | The scheme indicates the type of the target component of the contribution, and can be one of: |
| id | The unique identifier of the menu, toolbar or context (popup) menu where the contribution must be added. See the list below for standard platform identifiers that can be used. |
| placement | The arguments helps to define the placement of the contribution items in relation to another item or placeholder (i.e. GroupMarker) in the target menu. It consists of either the word "before" or "after" followed by an equal sign (=) and then the identifier of a menu contribution item. The word "additions" can also be used in place of an identifier. Contributions added to "additions" will typically be placed last in a menu. |
Talking in detail about the locationURI and menu contribution placement can be a long blog entry on its own, so I want to come to this subject in more detail later in the series.
Note: I usually declare my view's identifier as the same as the fully qualified Java class name of the ViewPart implementation class, and then use the convention viewID.menu, viewID.toolbar and viewID.popup as identifiers for its various menus. E.g. a View implemented in the class com.richclientgui.myreader.BookView will have the Id com.richclientgui.myreader.BookView and the menu IDs com.richclientgui.myreader.BookView.menu, com.richclientgui.myreader.BookView.toolbar and com.richclientgui.myreader.BookView.popup.
Platform Menu IDs
Some standard identifiers are available for commonly used menus and toolbars:
| ID | Description |
|---|---|
| org.eclipse.ui.main.menu | the main Eclipse application menubar |
| org.eclipse.ui.main.toolbar | the main Eclipse application toolbar |
| org.eclipse.ui.popup.any | contributions using this identifier will be visible in all context menus of the application (well, that's not the full truth, but that is a topic for another blog) |
| menu:file | three guesses what menu this one point to... |
| menu:help | I'm not even going to say its a menu, and you only get one guess |
| menu:window | Ok, you start to get the picture |
| helpEnd | name of group-marker at end of Help menu |
| quit | id of Exit action |
See IIDEActionConstants and IWorkbenchActionConstants for more useful identifiers.
I can't wait to move that Open eBook item to the top of the menu...
Running our latest version gives us a still grayed-out item, but at least where we want it.

And our plugin.xml has grown a bit:
|
Now to implement the behaviour.
Simple Handler (Behaviour)
After all this build-up, it is quite simple to actually add behaviour to a Command. You need to
Here is my DefaultOpenEBookHandler class:
|
If you run the application now, you will actually see that the command item in the menu is enabled, and you should see a dialog with a message if you select the item.
The Sum of the Parts
We saw a basic introduction of how to:
Each of these components on their own does not add value to an application, but together it forms a powerful yet flexible and very maintainable Commands framework, far superior to using IActions and IActionDelegates because of the separation between the intent, presentation and behaviour.
Summary of Steps
| Step 1 | Create sample RCP application |
| Step 2 | Add the org.eclipse.ui.commands extension to our plugin.xml |
| Step 3 | Declare the Open File command |
| Step 4 | Add the org.eclipse.ui.menus extension to plugin.xml |
| Step 5 | Add the MenuContribution element |
| Step 6 | Add the Command to the MenuContribution |
| Step 7 | Change Command menu-item placement |
| Step 8 | Implement a default Handler |
You can download the source code for this blog's version of the example.
Next Episode
Do not miss out on the next exciting episode on Eclipse RCP Commands. There I'll be tackling mind-blowing topics, like
(Time and weather permitting.)
References
Enough said for now.

3 comments:
Hi! i like this blog.... this template is simply super...
Increasing your web traffic and page views Add, add your website in www.itsolusenz.com
Post a Comment