Archive

Posts Tagged ‘plug-in’

Writing an Eclipse Plug-in (Part 24): Common Navigator: Configuring the submenus (Presentation…again)

August 29, 2010 9 comments

When we last left our erstwhile travelers (that would be all of you) they were surfing the quantum wave on their way to a future refactoring of their past to allow them to simultaneously feel proud of their work and embarrassed that they were following some guy who is making it all up as he goes along causing them to need refactoring in the first place.

Hey. Refactoring happens. All the time. Just ask evolution (only don’t mention the alligators).

What I will post about is adding behavior to our menu items. After having added 4 (count ’em) new menu items it is time to make them actually do something. What should they do? Well, they are going to add elements into their respective XML files (and respectively) while looking like they are adding items into their respective category nodes in the navigator.
Read more…

Writing an Eclipse Plug-in (Part 16): Custom Project: Customizing the Perspective Menus (Toolbar)

January 8, 2010 4 comments

In this post we will add three custom toolbar buttons to the main toolbar of the Custom Perspective of the Eclipse workbench.

Before we do that, I would like to point out that one of the default buttons on the toolbar is the New button. When you click on the downward pointing arrow of the New button you will see something shocking (shocking I say!): the same entries as we added to File –> New appear in the New toolbar button. That’s because they are tied together; change one and you change the other. We could disable it, but why not leave well enough alone? While it is true we didn’t mean to turn on this behavior we can bask in the glory of a job accidentally well done.

Life is full of disappointments.

Today we will add three buttons to the toolbar and have them create either a new Custom Project, Schema file or Deployment file. Seems kinda redundant in light of the behavior of the New toolbar button, but I want single custom command buttons in any case.

We need 3 new images; one for each button. I am reusing the images from a Hidden Clause Custom Project, Schema file and Deployment file:

How (are we doing it?)

Let’s add the buttons to the toolbar together with the configuration needed to open the appropriate New Wizards.

  1. Open plugin.xml
  2. Add –> org.eclipse.ui.menus
  3. org.eclipse.ui.menus –> menuContribution
    • locationURI: toolbar:org.eclipse.ui.main.toolbar
  4. toolbar:org.eclipse.ui.main.toolbar (menuContribution) –> toolbar
    • id: customplugin.toolbar
  5. customplugin.toolbar (toolbar) –> command
    • commandId: org.eclipse.ui.newWizard
    • label: New Custom Project
    • icon: icons/project-folder.png
    • tooltip: New Custom Project
    • style: push
  6. New Custom Project (command) –> parameter
    • name: newWizardId
    • value: customplugin.wizard.new.custom
  7. customplugin.toolbar (toolbar) –> command
    • commandId: org.eclipse.ui.newWizard
    • label: New Schema File
    • icon: icons/schema-file_16x16.png
    • tooltip: New Schema File
    • style: push
  8. New Schema File (command)–> parameter
    • name: newWizardId
    • value: customplugin.wizard.file.schema
  9. customplugin.toolbar (toolbar) –> command
    • commandId: org.eclipse.ui.newWizard
    • label: New Deployment File
    • icon: icons/deployment-file_16x16.png
    • tooltip: New Deployment File
    • style: push
  10. New Deployment File (command)–> parameter
    • name: newWizardId
    • value: customplugin.wizard.file.deployment
  11. Save plugin.xml
  12. Start the runtime workbench. Pressing any of the new buttons should open the appropriate New Wizard
  13. Hold the mouse over the buttons; the tooltips should display the string for which we configured each button

Oh oh! A bug! The toolbar buttons appear in all of the perspectives not just in the Custom Perspective. That behavior is just offensive; okay, maybe not offensive, but wrong in this case.

We will fix that with the following configuration.

  1. New Custom Project (command) –> visibleWhen
    • false (visibleWhen) –> with
      • variable: activeWorkbenchWindow.activePerspective
        • activeWorkbenchWindow.activePerspective (with) –> equals
          • value: customplugin.perspective
  2. New Schema File (command)–> visibleWhen
    • false (visibleWhen) –> with
      • variable: activeWorkbenchWindow.activePerspective
        • activeWorkbenchWindow.activePerspective (with) –> equals
          • value: customplugin.perspective
  3. New Deployment File (command)–> visibleWhen
    • false (visibleWhen) –> with
      • variable: activeWorkbenchWindow.activePerspective
        • activeWorkbenchWindow.activePerspective (with) –> equals
          • value: customplugin.perspective

So where did the variable name activeWorkbenchWindow.activePerspective come from? From Eclipse, of course! Oh, okay, take a look at the Command Core Expressions entry in the Eclipse wiki for more interesting variables you can use in your elements. We won’t be using any others…this time.

Why (did we do it that way?)

There is a lot of configuration going on here. There are only two obscure/interesting points.

Step #3:

  • org.eclipse.ui.menus –> menuContribution
    • locationURI: toolbar:org.eclipse.ui.main.toolbar

The locationURI field tells Eclipse where to place the three buttons: in the toolbar (hence the use of a scheme named toolbar) and which toolbar to use (the main toolbar which has an id of org.eclipse.ui.main.toolbar). Makes sense once you know it, but it would be helpful to have more examples. But that’s just me.

Step #1, 2 and 3 take care of hiding the toolbar buttons in all perspectives except the Custom Perspective.

  • false (visibleWhen) –> with
    • variable: activeWorkbenchWindow.activePerspective
      • activeWorkbenchWindow.activePerspective (with) –> equals
        • value: customplugin.perspective

The visibleWhen element works with the usual choices of adapt, and, count, equals, etc. By selecting the with element you have to supply one of the variables listed in the Command Core Expressions listed in the Eclipse wiki. At runtime the variable activeWorkbenchWindow.activePerspective contains the id of the current perspective so including the equals element with the id of the Custom Perspective (customplugin.perspective) means that the only time the selected button will appear is when the Custom Perspective is open.

Don’t forget to open plugin.xml and externalize the new strings otherwise you will be stuck with a bunch of warnings that are not worth tolerating.

What Just Happened?

In today’s episode:

  • we added 3 buttons to the main toolbar
  • configured the toolbar buttons to open the appropriate wizards
  • configured the toolbar buttons to only appear in the custom perspective

Once again, we have managed to add a significant amount of behavior and not had to write any code. It doesn’t get any better than that (well, maybe it does, but I’m not sure if I’m ready to brag about that kind of thing).

Thanks

David Carver and his blog entry Adding Wizards To Toolbars.

Code

Oh, yeah. None.

However, there are the entries in the plugin.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.2"?>
<plugin>
   <extension
         point="org.eclipse.ui.newWizards">
      <category
            id="customplugin.category.wizards"
            name="%category.name">
      </category>
      <wizard
            category="customplugin.category.wizards"
            class="customplugin.wizards.CustomProjectNewWizard"
            finalPerspective="customplugin.perspective"
            icon="icons/project-folder.png"
            id="customplugin.wizard.new.custom"
            name="%wizard.name">
      </wizard>
      <wizard
            category="customplugin.category.wizards"
            class="customplugin.wizards.CustomProjectNewSchemaFile"
            descriptionImage="icons/schema-file_32x32.png"
            icon="icons/schema-file_16x16.png"
            id="customplugin.wizard.file.schema"
            name="%wizard.name.schema">
      </wizard>
      <wizard
            category="customplugin.category.wizards"
            class="customplugin.wizards.CustomProjectNewDeploymentFile"
            descriptionImage="icons/deployment-file_32x32.png"
            icon="icons/deployment-file_16x16.png"
            id="customplugin.wizard.file.deployment"
            name="%wizard.name.deployment">
      </wizard>
   </extension>
   <extension
         point="org.eclipse.ui.perspectives">
      <perspective
            class="customplugin.perspectives.Perspective"
            icon="icons/perspective.png"
            id="customplugin.perspective"
            name="%perspective.name">
      </perspective>
   </extension>
   <extension
         point="org.eclipse.ui.perspectiveExtensions">
      <perspectiveExtension
            targetID="customplugin.perspective">
         <view
               id="customnavigator.navigator"
               minimized="false"
               ratio=".25"
               relationship="left"
               relative="org.eclipse.ui.editorss">
         </view>
      </perspectiveExtension>
   </extension>
   <extension
         id="customplugin.projectNature"
         point="org.eclipse.core.resources.natures">
      <runtime>
         <run
               class="customplugin.natures.ProjectNature">
         </run>
      </runtime>
   </extension>
   <extension
         point="org.eclipse.ui.ide.projectNatureImages">
      <image
            icon="icons/project-folder.png"
            id="customplugin.natureImage"
            natureId="customplugin.projectNature">
      </image>
   </extension>
   <extension
         id="customplugin.contenttype"
         point="org.eclipse.core.contenttype.contentTypes">
      <content-type
            base-type="org.eclipse.core.runtime.xml"
            file-extensions="xml"
            id="customplugin.contenttype.schema"
            name="%content-type.name.schema"
            priority="normal">
         <describer
               class="org.eclipse.core.runtime.content.XMLRootElementContentDescriber2">
            <parameter
                  name="element"
                  value="hc-schema">
            </parameter>
         </describer>
      </content-type>
      <content-type
            base-type="org.eclipse.core.runtime.xml"
            file-extensions="xml"
            id="customplugin.contenttype.deployment"
            name="%content-type.name.deployment"
            priority="normal">
         <describer
               class="org.eclipse.core.runtime.content.XMLRootElementContentDescriber2">
            <parameter
                  name="element"
                  value="hc-deployment">
            </parameter>
         </describer>
      </content-type>
   </extension>
   <extension
         point="org.eclipse.ui.perspectiveExtensions">
      <perspectiveExtension
            targetID="customplugin.perspective">
         <newWizardShortcut
               id="customplugin.wizard.new.custom">
         </newWizardShortcut>
         <newWizardShortcut
               id="customplugin.wizard.file.schema">
         </newWizardShortcut>
         <newWizardShortcut
               id="customplugin.wizard.file.deployment">
         </newWizardShortcut>
      </perspectiveExtension>
   </extension>
   <extension
         point="org.eclipse.ui.menus">
      <menuContribution
            locationURI="toolbar:org.eclipse.ui.main.toolbar">
         <toolbar
               id="customplugin.toolbar">
            <command
                  commandId="org.eclipse.ui.newWizard"
                  icon="icons/project-folder.png"
                  label="%customproject.label"
                  style="push"
                  tooltip="%customproject.tooltip">
               <parameter
                     name="newWizardId"
                     value="customplugin.wizard.new.custom">
               </parameter>
               <visibleWhen
                     checkEnabled="false">
                  <with
                        variable="activeWorkbenchWindow.activePerspective">
                     <equals
                           value="customplugin.perspective">
                     </equals>
                  </with>
               </visibleWhen>
            </command>
            <command
                  commandId="org.eclipse.ui.newWizard"
                  icon="icons/schema-file_16x16.png"
                  label="%schema.label"
                  style="push"
                  tooltip="%schema.tooltip">
               <parameter
                     name="newWizardId"
                     value="customplugin.wizard.file.schema">
               </parameter>
               <visibleWhen
                     checkEnabled="false">
                  <with
                        variable="activeWorkbenchWindow.activePerspective">
                     <equals
                           value="customplugin.perspective">
                     </equals>
                  </with>
               </visibleWhen>
            </command>
            <command
                  commandId="org.eclipse.ui.newWizard"
                  icon="icons/deployment-file_16x16.png"
                  label="%deployment.label"
                  style="push"
                  tooltip="%deployment.tooltip">
               <parameter
                     name="newWizardId"
                     value="customplugin.wizard.file.deployment">
               </parameter>
               <visibleWhen
                     checkEnabled="false">
                  <with
                        variable="activeWorkbenchWindow.activePerspective">
                     <equals
                           value="customplugin.perspective">
                     </equals>
                  </with>
               </visibleWhen>
            </command>
         </toolbar>
      </menuContribution>
   </extension>

</plugin>

OSGI-INF/I10n/bundle.properties

#Properties file for customplugin
Bundle-Name = Customplugin Plug-in
category.name = Custom Wizards
wizard.name = Custom Project
perspective.name = Custom Plug-in Perspective
content-type.name.schema = Hidden Clause Schema Definition
content-type.name.deployment = Hidden Clause Deployment Definition
wizard.name.schema = Schema File
wizard.name.deployment = Deployment File

customproject.label = New Custom Project
customproject.tooltip = New Custom Project
schema.label = New Schema File
schema.tooltip = New Schema File
deployment.label = New Deployment File
deployment.tooltip = New Deployment File

Writing an Eclipse Plug-in (Part 15): Custom Project: Customizing the Perspective Menus (Main menu)

December 19, 2009 5 comments

Ah! Nothing like returning to the scene of the crime.

When we were last at the crime scene we were displaying projects in the Custom Navigator in various states of openness and closedness. What could possibly be next? Well, there are a few choices:

  • Customize the Custom Perspective so our current capabilities are available in the main workspace menu, toolbar and Customize Perspective window.
  • Add navigator popup menus to do things like New, Copy and Properties
  • Display information in the project structure

Even though I expect to create a Form-based editor to hide the ugliness of an XML file that is not necessarily the task of greatest import. In this post I am going to show how to add menu items to our Custom Perspective; we will customize the Custom Navigator popup menu in a future post.

We should always be implementing with the end in mind as a way of keeping extraneous features to a minimum anyway. At least that’s my story.

What (are we doing?)

There are about 7 ways to do almost anything in Eclipse. For example, if you want to open the New Wizard you could go about doing that in the following ways:

  1. Ctrl+N
  2. Main menu: File –> New
  3. Shift+Alt+N – opens the popup menu; select New
  4. Right click on a Project and select New
  5. Right click on a Folder and select New
  6. Toolbar: New button
  7. Toolbar: Java Class button: New: JUnit Test, Class, Interface, Enum, Annotation

And those were just the ones I thought of off the top of my head (okay, so maybe I tried them all first…).

So, in order to compete with all of the other plug-ins out there a plug-in developer has to make sure there are at least a minimum of ways to activate their plug-in: CRUD functionality (New, Open, Save, Delete), opening editor(s) and view(s), open the Properties window, etc.

The good news: Ctrl+N and Shift+Alt+N open the New Wizard window in every case (unless you change the key bindings) so we can safely ignore them.

The bad news: we only have a New Wizard for Custom Projects and two file types. This means that the only way to create a custom resource is either from the main menu (File –> New –> Other), Ctrl+N, or Shift+Alt+N. Since all three will activate the default New Wizard we have not gained anything.

The lesson to learn here is when you add something to the New Wizard your task list should include updating your perspective to support the:

  • Main Menu File menu
  • Toolbar
  • Customize Perspective window

Notice how the only thing this will do is make your existing behavior available in more places. Not a bad thing, just kinda extraneous; convenient for the user, feels like busy work for the developer.

You could also decide to add your GUI functionality to all of the perspectives, but beware: each perspective is specific to the task at hand. Adding the ability to do random things in arbitrary perspectives is bad form. Add functionality to specific perspectives as appropriate (what that means will vary with the capability you are implementing). Adding plugin.xml to a COBOL project doesn’t really mean anything. The road to menu pollution is paved with good intentions. Don’t be afraid to create custom perspectives where you can just go to town adding whatever you want with impunity.

So the tasks for the next few blogs are to add:

  • In the main menu: add Custom Projects, Schema, and Deployment files to File –> New
  • In the Toolbar: add a toolbar group for the above 3 items
  • In Customize Perspective: add the ability to enable/disable all of the above

In the Customize Perspective window adding the ability to enable/disable the above capabilities means:

  • Toolbar Visibility: Custom Project Element Creation (enable by default)
    • Custom Project
    • Schema File
    • Deployment File
  • Menu Visibility: File –> New, (already available, enable by default)
    • Custom Project
    • Schema File
    • Deployment File
  • Command Group Availability: Custom Project Element Creation (enable by default)
  • Shortcuts (affects Menu Visibility; enable by default)
    • New
      • Custom Project
      • Schema File
      • Deployment File
    • Open Perspective (Affects main menu Windows –> Open Perspective)
      • Resource (available, but not enabled)
    • Show View (Affects main menu Windows –> Open View)
      • Custom Plug-in Navigator (available, but not enabled)

How (are we doing it?)

In the main menu: add Custom Projects, Schema, and Deployment files to File –> New

Adding New Wizard entries onto the menu menu is done completely by configuration (my favorite).

  1. Open up plugin.xml for customplugin
  2. Go to Extensions–> Add –> perspectiveExtension and click Finish (yes, you could skip this step and use the existing perspectiveExtension entry)
  3. Change
    • targetID: *

    to

    • targetID: customplugin.perspective
  4. Right click on customplugin.perspective (perspectiveExtension) –> new –> newWizardShortcut
  5. Select newWizardShortcut and enter:
    • ID: customplugin.wizard.new.custom
    • The above is the id of the New Custom Project Wizard entry under org.eclipse.ui,newWizards –> Custom Project (wizard)
  6. Perform steps 4 and 5 for the Schema File (wizard) and Deployment File (wizard)
  7. Save plugin.xml

To make them appear in all of the perspectives change (do not try this at home. I am a trained professional):

  • Extensions –> perspectiveExtension –> targetID: customplugin.perspective

to

  • Extensions –> perspectiveExtension –> targetID: *

Remember, only you can prevent menu pollution.

As a wonderful side-effect the Customize Perspective window has the three New wizard entries entered automatically. Start the runtime workbench, open the Customize Perspective window (Windows –> Customize Perspective), select Menu Visibility and open File –> New.

In addition select the Shortcuts tab of the Customize Perspective window and see that for Submenu New the Shortcut Category has Custom Wizards selected and the three wizards are already checked.

The Toolbar tab and the Command Groups Availability tab are both devoid of entries for our Custom Project. Are we going to take care of that now? Well…no. Next time. Really. I know you’re disappointed, but if you push me I’ll make sure you get a lump of coal.

What Just Happened?

Configuration. Nothing like it for tedious tasks.

How much code did we write: none. It is going to be a good holiday.

Well, that’s it for this entry. It is Sunday, the holidays are getting closer and I was lucky to get this post out.

Next time: Adding the New Wizard functionality to the Toolbar. Maybe. If I get a Sega R-360.

Yuletide Felicitations!

Writing an Eclipse Plug-in (Part 3): Create a custom project in Eclipse – New Project Wizard: Time to Refactor

July 19, 2009 4 comments

In my last post I showed how to get the GUI aspect of a New Wizard for the creation of a new project type up and running rather quickly. In my never ending attempt to be a good developer citizen it is now time to stop and refactor.

You might think we haven’t actually written enough code to refactor (we have 3 Java files in total). That would be true except for the three strings in our wizard code. I could wait until there is more to do, but why not refactor now when it will begin to develop muscle memory for that particular task?

First change:

    _pageOne = new WizardNewProjectCreationPage("Custom Plug-in Project Wizard");

to:

    _pageOne = new WizardNewProjectCreationPage(PAGE_NAME);

and put the string at the top of the class:

    private static final String PAGE_NAME = "Custom Plug-in Project Wizard"; //$NON-NLS-1$

Next change:

    public CustomProjectNewWizard() {
        setWindowTitle("New Custom Plug-in Project");
    }

to:

    public CustomProjectNewWizard() {
        setWindowTitle(WIZARD_NAME);
    }

and put the new constant at the top of the class:

    private static final String WIZARD_NAME = "New Custom Plug-in Project"; //$NON-NLS-1$

The other two strings should be replaced by using the Eclipse Externalize Strings mechanism. With the CustomProjectNewWizard.java open in the editor select Source –> Externalize Strings (or move the cursor to one of the strings and press Ctrl+1).

When the Externalize Strings dialog opens check the box for Use Eclipse’s String Externalization Mechanism. If you like the key value then leave them alone, but I prefer to have a variable name that conveys some level of information so I changed the keys to match the strings; so the CustomProjectNewWizard_0 becomes CustomProjectNewWizard_Custom_Plugin_Project and CustomProjectNewWizard_1 becomes CustomProjectNewWizard_Create_something_custom.

In addition, click Configure which is next to the Accessor Class dropdown field. Change the Class Name from Messages to NewWizardMessages. Click OK to finalize your decision.

Press Next in the Externalize Strings dialog to take a look at what the change will look like. What you should see are the strings replaced with a reference to a new class that just got generated.

    _pageOne.setTitle(NewWizardMessages.CustomProjectNewWizard_Custom_Plugin_Project);
    _pageOne.setDescription(NewWizardMessages.CustomProjectNewWizard_Create_something_custom);

Look in the Package Explorer for the new class. It should be in the same package as the Wizard code. The magic? At runtime Eclipse reads the property file named messages.properties and fills in the static fields with the values in the file. You can add to the file through the Externalize Strings dialog as you add more strings that need to be externalized.

That is the extent of the refactoring based on what has been done so far.

Refactoring can sometimes seem trivial, but it will pay many dividends later when a string needs to be changed, or internationalized, and the only thing that needs to be done is to create a new properties file.

My Eclipse Plug-in Stopped Working After I Copied It Onto My Linux Box!

February 17, 2009 Leave a comment

I ran into an interesting problem the other day: I was copying my Eclipse workspace from my Windows Vista box to a Linux environment and the plug-in stopped working (when I say not working I mean that I double-clicked on plugin.xml and the Plug-in Development Environment treated it like an empty plug-in: no name., no id, no dependencies…nothing). I have been working on and off on a plug-in, keeping copious notes as I want to blog about the various things I have been doing for future blogs, when I found that the plugin.xml file appeared to be disconnected from the plug-in project itself.

Rather than write my usual wordy post here is the solution: when the plug-in was created/copied on Windows the META-INF/MANIFEST.MF files somehow ended up in lower case. When I copied the workspace to the Linux box the Eclipse plug-in development environment did not know what to make of the new lower case names and so did what any self-respecting IDE would do: Eclipse ignored it.

Rename the folder and file to upper case: META-INF/MANIFEST.MF. The project will come back to life. Life goes on.