Eclipse Search

Loading

Jan 2, 2009

Commands Part 1: Actions Vs Commands

As you would have seen, there are two different ways to contributing to the Workbench: Actions and Commands. Although Commands are newer and advanced, I've always preferred using Actions, simply because of my comfort level in using them. Now that I've started fixing some bugs in the Command framework, I'm forced to look into the details. The more deeper I look into the Commands, the more I'm loving it. So I decided to write a series of on the Commands and this is the first one in the series. Many of the information presented here is obtained by looking some old bugs, wiki and digging into CVS history. If I'm missing anything or wrong about something let me know.

Lets start with Actions. We are able to contribute to the menus, toolbars, pull down menu, etc. We are able to specify the UI details like label or tooltip in the plugin.xml itself, which helps in lazy loading. So whats wrong with them?
  • The UI and handling are always tied. There is no way you can separate each other
  • While Actions can be contributed to different parts of the workbench (popup menu/tool bar), all of them were different extension points and so you end up duplicating the XML in multiple places. The worst of it is that not all the extension points expect the same configuration.
  • Specifying Actions in multiple places is a maintenance nightmare. If you have to change the icon of an action, you need to change in all the places.
  • Another issue with duplicating Actions in plugin.xml is that multiple instance of the same Actions will be created in the memory
Lets see how the Commands Framework eliminates all this. Commands are defined by the org.eclipse.ui.commands extension point. A typical command would look like:

<command
         id="com.eclipse-tips.commands.someCommand"
         name="Some Command">
</command>


Yeah thats it. That defines a Command! If you want to place this in a tool bar, you have to use the extension point org.eclipse.ui.menus:

<menuContribution
      locationURI="toolbar:org.eclipse.ui.main.toolbar">
   <toolbar
         id="com.eclipse-tips.commands.toolbar1">
      <command
            commandId="com.eclipse-tips.commands.someCommand"
            id="com.eclipse-tips.commands.someCommandInToolBar">
      </command>
   </toolbar>
</menuContribution>

 
Now that takes of the placement in the UI. But what about the code that gets executed? That goes into a another extension point, org.eclipse.ui.handlers:

<handler
         class="com.eclipse_tips.commads.SomeCommandHandler"
         commandId="com.eclipse-tips.commands.someCommand">
</handler>


One last piece is to add an icon to the Command
No price for guessing that you need to use another extension point, org.eclipse.ui.commandImages:

<image
         commandId="com.eclipse-tips.commands.someCommand"
         icon="icons/sample.gif">
</image>


All set. Lets see the Command in action:
image
As you see, in the actions we would just use only one extension point, instead of the four which we have used now. Does it sounds like a round about way or doing things? Probably once we get to know about multiple handlers for a Command and context based association & enablement of the handlers etc, we will see the beauty of the framework. That would be the next in this series.

Update (31-Mar-2009): Thanks to Hiroki Kondo, a Japanese version of this blog entry is available here.

Update (29-Sep-2009): Thanks to Peng Zhang, a Chinese version of this blog entry is available here.


See also:
Part 2: Selection and Enablement of Handlers
Part 3: Parameters for Commands
Part 4: Misc items ...
Part 5: ISourceProvider & dynamically updating Commands
Part 6: 'toggle' & 'radio' style menu contribution

16 comments:

  1. Thanks for this, I wanted to use commands and menuContributions and was just about to start digging for clues. Your blog saved me the effort.

    ReplyDelete
  2. Hi, it would be also nice if you cover advanced topics like property testers in your series.

    ReplyDelete
  3. Hi,

    I relation to this: "As you see, in the actions we would just use only one extension point, instead of the four which we have used now."

    You could have done this with two extensions points by using the default handler and the icons in the menucontributin.

    Please see here for an explaination: http://www.vogella.de/articles/RichClientPlatform/article.html#commands

    Best regards, Lars

    ReplyDelete
  4. Hi,

    Can commands be used to override the Copy/Paste/Delete/Rename/... commands (retargetable actions)?

    If yes, how it works?

    Thanks

    ReplyDelete
  5. > Can commands be used to override the
    > Copy/Paste/Delete/Rename/... commands (retargetable actions)?

    Short answer is yes, the long answer will be posted as a separate tip :-)

    ReplyDelete
  6. What do I have to do to get you to turn these blog posts into an article for Eclipse Corner?

    I can get you an Eclipse-branded shirt... I can help you write it...

    ReplyDelete
  7. @Wayne,
    2 more posts in this series are still pending. I'll make it as an article once they are done.

    ReplyDelete
  8. Hi Prakash,

    Did you write the 2 posts you mentionned in the last comment?

    What are the subjects?

    Is the copy/paste/undo/redo is one of this subject?

    Thanks,
    Vincent

    ReplyDelete
  9. Hello!

    Thanks for writing the good explanation.

    I have a question: Can I use the command framework with extension points which expect Actions? For example, can I somehow contribute a Command to an extension point like org.eclipse.ui.PopupMenus ?

    This one seems useful as it gives the possibility to add a popup menu to an object regardless of where it is displayed.

    Best regards,
    -- Kos

    ReplyDelete
  10. @Kos,
    Yes you can use commands in popup menus. You need to use the o.e.ui.menus and the URI should start with "popup:" See: http://wiki.eclipse.org/Menu_Contributions

    ReplyDelete
  11. I'm also interested in finding out more about retargetable actions using the new commands framework.

    I've tried converting all my menus using the new commands framework, and now my undo action is not working.


    OLD WAY (in fillMenuBar):
    IAction action = ActionFactory.UNDO.create(window);
    menuManager.add(action);
    getActionBarConfigurer().registerGlobalAction(action);

    NEW WAY (in plugin.xml):
    <command
    commandId="org.eclipse.ui.edit.undo"
    id="undo"
    label="Undo"
    style="push">
    </command>


    Is there a way to emulate registerGlobalAction() declaratively?

    I've found a few old posts with people running into the same problem, but haven't found any answers, and google isn't turning up anything.

    Great blog post BTW (very useful)!

    ReplyDelete
  12. @Anon,

    There is no way to go away without registering. It should be possible when this gets fixed: https://bugs.eclipse.org/bugs/show_bug.cgi?id=270007

    ReplyDelete
  13. @Prakash-

    Thanks for the feedback! Actually, last night after asking you this, I went ahead and overrode makeActions() in ActionBarAdvisor:

    protected void makeActions(IWorkbenchWindow window) {
    super.makeActions(window);
    register(ActionFactory.UNDO.create(window));
    }

    So while the UNDO command is not entirely declarative (in plugin.xml), I still don't *need* to use fillMenuBar() to make my menus, so I can follow the examples in your tutorial. I just need to remember to use makeActions() when dealing w/ RetargetActions.

    Thanks for the explanation and the link to the bug.

    ReplyDelete
  14. hi prakash,

    great post.
    i wanna ask question.
    how to override eclipse popupmenu action?
    i want to override eclipse delete action.

    ReplyDelete
  15. I'm developing a plugin that uses the standard project explorer view and
    I want to replace the default "delete" handler. My plugim.xml file
    contains the following handler:















    The handler works correctly :
    1- in the Edit/Delete menu
    2- or when I press the Delete key (via key binding)

    However, when I right click on a resource in Project Explorer and click
    on the Delete popup menu item, my handler is ignored and the default
    handler is called. Why is my handler ignored when the delete command is
    called from the context menu of the project explorer and works correctly
    from menu and key binding?

    Any help will be appreciated. Thank You.

    Darshan

    ReplyDelete
  16. Hello,
    is it possible to execute an Action programmatically as you shown for Commands?

    ReplyDelete