Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Working XML: Creating a project

Adding new wizards to Eclipse

Benoit Marchal, Consultant, Pineapplesoft
Benoît Marchal is a consultant and writer based in Namur, Belgium. He is the author of XML by Example and other XML books covering the latest features of the XML standard, including the final XML Schema recommendation and the latest developments of XSL. More details are available at www.marchal.com. You can contact Benoît at bmarchal@pineapplesoft.com.

Summary:  Work continues on the integration of Eclipse -- IBM's open-source project to build an extensible Integrated Development Environment (IDE) for Java developers -- and Benoît Marchal's simple content-management solution known as XM. In this installment, Benoît adds a wizard to initialize a new project. In the process, he shares some of his hard-earned findings about the Eclipse platform.

View more content in this series

Date:  01 Oct 2010 (Published 01 Jan 2003)
Level:  Intermediate PDF:  A4 and Letter (110KB | 12 pages)Get Adobe® Reader®
Also available in:   Japanese

Activity:  11844 views
Comments:  

01 Oct 2010 - Corrected two broken links Resources.

If you have been following this project since the beginning, you know that I am enthusiastic about Eclipse. As Emacs fans will tell you, a good development environment has to be extensible and configurable. Eclipse delivers on both counts, but unlike its prestigious ancestor Emacs, Eclipse also offers a modern user interface.

Portability of SWT

One of the best things about Eclipse is that it fixes what I consider to be one of the most frustrating deficiencies in Java technology: The user interface library. As I have already reported, Eclipse uses the Standard Widget Toolkit (SWT), which combines the best features of the Abstract Windowing Toolkit (AWT), the use of native controls, and Swing's rich set of widgets. At last, it's possible to design sophisticated user interfaces that behave like their native counterparts.

Most of the criticism of SWT has centered on portability. Since SWT is not part of the JDK (Java Development Kit), it may not be available on some platforms. Fortunately, the Eclipse team seems committed to porting SWT to as many platforms as necessary, so in practice it should not be a problem.

I was curious to test the portability of SWT, so when it became available I downloaded the Macintosh build. Although it is still under development, the Mac port is reasonably stable. I was most impressed, though, with SWT and its ability to paint native Aqua controls.


On documentation

It's fun to use new projects and report on them, but there's a downside as well: Documentation for a new project is often deficient. Eclipse is no exception. Writing this article -- or rather coding for it -- required a lot of research. The documentation is limited to a few articles on the principles, documentation of the API, and, fortunately, the source code.

The development session was mostly trial and error -- working on code until it did something sensible. Unfortunately, I frequently thought I understood something and moved on to a new task only to find that I was wrong! Eventually, I reached a point where I was confident in my understanding. None of the isolated issues I faced was crucial, but the combination of problems was challenging. As more articles are written, the (lack of) documentation issue should eventually fade away.


XM plug-in evolution

Working XML forum

We have new forum software that is easier to use, so make sure you join the discussion -- on XML, other column projects, or Eclipse -- by clicking Discuss at the top or bottom of this article.

At the end of the previous column, "Integrating XM and Eclipse," I had achieved a crude integration of XM with Eclipse. I added an entry to the contextual menu, which the user could select to run XM. I knew it was only a first step, but as I (and others at Pineapplesoft) started using it, I realized I needed to do much better. Specifically, I complained that:

  • Starting a new project is difficult. I had to run the New Project wizard, then manually create several files. The wizard should take care of everything.
  • The .xmp file was confusing. In most cases it's empty, since it is only required as a click target. Originally XM needed no configuration files, which was part of its attraction.
  • Right-clicking is a Windows/KDE/Gnome gesture. On the Mac, right-clicking is best left for complex, infrequent operations. I had to come up with a more portable interface. It is possible to register builders (essentially compilers) with Eclipse. Eclipse automatically invokes the appropriate builders when the project changes.

With these shortcomings in mind, I decided that for the immediate future, the XM plug-in should include a New Project wizard and the ability to invoke XM during a project build. These two features are implemented through extension points. (Turn to the "Use Eclipse to build a user interface for XM" article in Resources for more details on extension points.) The extension point for a new wizard is org.eclipse.ui.newWizards and it uses the interface org.eclipse.ui.INewPlugin. The extension point for a builder is org.eclipse.core.resources.builders and it uses the interface org.eclipse.core.resources.IncrementalProjectBuilder.


New project wizard

The new project wizard and the builder are related. For example, Eclipse will automatically invoke the builder when creating a new project. If you download the code from the online repository, you will see that both have been implemented. This article covers the wizard, while next month's article will cover the builder.

Files and project directories

Let's start with some definitions. For Eclipse, a project is a set of files (source files, configuration files, compiled files, and more) in a project directory. In Eclipse jargon, files and directories are called resources. Do not confuse Eclipse resources (files) with Java resources (strings used for localization).

The list of projects available to the user constitutes the workspace. By default the projects are stored under the eclipse/workspace directory, but the user can create projects anywhere.

The user interacts with the projects through the navigator panel, as shown in Figure 1. Again, plug-ins can contribute specialized navigators. Figure 1 is the generic navigator that lists the resources (files) in the projects.


Figure 1. The Eclipse navigator
Eclipse navigator

To create a new project, you need a new directory and several configuration files that Eclipse manages. Note that it's not enough to create a new directory in the workspace -- Eclipse would not recognize it as a project.

Project nature

The main configuration file for a project is called .project (the dot marks a hidden file on UNIX file systems). It contains information on how to build the project as well as the project nature.

The nature is an identifier for the project type. For example, the Java project has the Java nature. Eclipse uses the project nature to control the interaction with the user. The nature may enable or disable menu items, so a project with the Java nature has Java-specific items in the menu.

A project can have more than one nature. For example, a plug-in project is both a Java project (after all, plug-ins are written in the Java language) and a plug-in project. In practice, it gets menu entries for both.

Like other Eclipse identifiers, nature identifiers start with a domain name in reverse order, not unlike package names. For example, the Java nature identifier is org.eclipse.jdt.core.javanature. Be careful not to confuse this identifier with a class/package name. Turn to "Use Eclipse to build a user interface for XM" in the Resources section for more details on identifiers.

Having learned this, I realized that the project nature makes the dummy .xmp file (introduced in the previous column) redundant. If I define a special nature for XM projects, it is possible to associate the Run XM menu item introduced in Integrating XM and Eclipse with those projects.

I defined org.ananas.xm.eclipse.xmnature as the project nature for XM. Listing 1 illustrates how I modified the manifest (plugin.xml) to reflect this.


Listing 1. New extension point
		
<extension point="org.eclipse.ui.popupMenus">
   <objectContribution adaptable="true"
         objectClass="org.eclipse.core.resources.IResource"
         id="org.ananas.xm.eclipse.popupMenu">
      <filter name="projectNature"
            value="org.ananas.xm.eclipse.xmnature">
      </filter>
      <action label="Run XM"
              tooltip="Call XM to publish the site."
              class="org.ananas.xm.eclipse.XMRunner"
              menubarPath="additions"
              enablesFor="+"
              id="org.ananas.xm.eclipse.popMenu.action">
      </action>
   </objectContribution>
</extension>

If you compare Listing 1 with the code published previously, you will see the following changes:

  • The filter tag replaces the nameFilter attribute. filter matches on project nature, nameFilter matched on filenames.
  • The enablesFor attribute was changed to +, which means that several files in the project can be selected. This is just a convenience for the user.
  • The XMRunner class is mostly unchanged. I have shortened the package name, though, to save some typing.

New XM project wizard

Obviously the manifest in Listing 1 only works if the project has been declared as the XM nature. The generic wizard creates projects that have no nature. So to test the code in Listing 1, I first need to provide an XM project wizard.

Eclipse wizards

Eclipse is incredibly extensible and this is reflected in how it treats wizards. With Eclipse, several plug-ins can contribute to a wizard. The project wizard takes advantage of this feature.

When the user selects New Project in the menu, the wizard shown in Figure 2 displays. The user selects the type of project to create. Although XM appears in the list, the XM plug-in has not yet been loaded. The list is populated from the manifest (plugin.xml).


Figure 2. New project wizard
New Project Wizard

However on the next screen, shown in Figure 3, the plug-in has been loaded and given control of the screen. The transition is very smooth for the user: The wizard does not flicker or change in any way. In fact, unless the user has written a plug-in, he may never realize that a new plug-in has been loaded.


Figure 3. The plug-in has been loaded
The plug-in has been loaded

To achieve this transparent integration, Eclipse breaks a wizard into three sets of objects:

  • The container is the dialog box with the buttons.
  • The wizards respond to user actions. A container interacts with one or more wizards to respond to user actions.
  • The pages draw the controls within the container. Each time the user presses the Next button, a new page is loaded. In Figure 3, the page manages the fields for the project name and directory.

XM implementation

XM implements the wizard in the NewXMProjectWizard class. The class implements the INewWizard interface. In practice, the easiest solution is to derive from Wizard since this class is a default implementation for most methods defined by INewWizard.

NewXMProjectWizard was registered as an extension point in the manifest, as always. Listing 2 is the relevant excerpt from the manifest. Notice that it declares a category for the wizard. This category would group several XM wizards.


Listing 2. Wizard extension point
		
<extension point="org.eclipse.ui.newWizards">
   <category name="ananas.org"
             id="org.ananas.xm.eclipse.newWizards">
   </category>
   <wizard name="XM Project"
           icon="icons/newproject16.gif"
           category="org.ananas.xm.eclipse.newWizards"
           class="org.ananas.xm.eclipse.NewXMProjectWizard"
           project="true"
           id="org.ananas.xm.eclipse.newproject">
      <description>Create an XM project.</description>
   </wizard>
</extension>

The wizard tag is new to wizards, but it is very similar to the view introduced in the previous column, so it should be familiar. The only novelty is the project attribute: When set to true, it adds the wizard to the new project list. Without this attribute, the wizard is listed in the "Other" category.

After loading the plug-in, the container calls init(). NewXMProjectWizard needs little initialization. First it calls setNeedsProgressMonitor() to request a progress bar. While creating the project, it increments the bar, as shown in Listing 3.


Listing 3. The init() method
		
public void init(IWorkbench workbench,
                 IStructuredSelection selection)
{
   setNeedsProgressMonitor(true);
}

Next, the container calls addPages() as shown in Listing 4. The method registers the wizard pages. NewXMProjectWizard needs only one page that prompts for the project name and location. Eclipse conveniently provides such a page in class WizardNewProjectCreationPage (you can see this page in Figure 2).


Listing 4. The addPages() method
		
public void addPages()
{
 super.addPages();
 namePage = new WizardNewProjectCreationPage("NewXMProjectWizard");
 namePage.setTitle(Resources.getString("eclipse.newprojectname"));
 namePage.setDescription(Resources.getString("eclipse.newprojectdescription"));
 namePage.setImageDescriptor(ImageDescriptor.createFromFile(getClass(),
       "/org/ananas/xm/eclipse/resources/newproject58.gif"));
 addPage(namePage);
}

The wizard calls addPage() for every page it registers. In this case, that's one page only.

User clicks finish

The performFinish() method executes when the user clicks Finish. Listing 5 is the method content. Not much happens in this method. The bulk of the project creation is in createProject(), which performFinish() calls indirectly.


Listing 5. The performFinish() method
		
public boolean performFinish()
{
   try
   {
      WorkspaceModifyOperation op =
         new WorkspaceModifyOperation()
      {
         protected void execute(IProgressMonitor monitor)
         {
            createProject(monitor != null ?
                          monitor : new NullProgressMonitor());
         }
      });
      getContainer().run(false,true,op);
   }
   catch(InvocationTargetException x)
   {
      reportError(x);
      return false;
   }
   catch(InterruptedException x)
   {
      reportError(x);
      return false;
   }
   return true; 
}

Creating a project modifies the workspace, since it adds directories and files. The wizard synchronizes itself with the workspace throughout the modification. The easiest solution is to execute the project creation in a descendant of WorkspaceModifyOperation.

The code that modifies the workspace must be called from the execute() method. In Listing 5, it simply calls createProject(). execute() takes an IProgressMonitor as an argument. If the project creation takes time, the wizard reports on its progress through this argument. The container uses it to update a progress bar.

The most useful methods on IProgressMonitor are:

  • beginTask(), which should be called before the operation starts. It takes a description and the duration of the operation.
  • worked() reports on the progress. It typically updates a progress bar.
  • done() must be called when the project is created.
  • subTask() lets you change the description.

The length of the project creation and the progress is reported in units of work. It's up to you to define what a unit represents. For example, when processing files, each unit could be a file.

To execute the thread, call the run() method on the container. The container synchronizes its progress bar with the IProgressMonitor.

Project creation

The actual project creation takes place in createProject() (see Listing 6). The order is very important in this method: The wizard will fail (often with confusing error messages) if your code does not follow the proper order.

To create a new project, follow these steps:

  1. Retrieve the workspace root as an instance of IWorkspaceRoot. Eclipse provides a convenient plug-in (ResourcesPlugin) through which you can access resources, including the workspace. Again, these are Eclipse resources such as files and directories.
  2. Call getProject() on IWorkspaceRoot. (Personally, I think the method should have been called newProject() because it creates the project.)
  3. Create an empty project description with the newProjectDescription() method. The project description holds certain types of information about the project, including where it is located on the file system.
  4. If the user chooses the default location (under the workspace directory), move to the next step. Otherwise, set the location on the description object. For some reason, project creation fails if you explicitly set the project location to its default.
  5. Register the project natures, if any. This is an array of string identifiers.
  6. Register the project builders (or compilers). Although I cover it in the next article, XM is now available as a builder.
  7. Create the project with the create() method.
  8. Finally, open the newly created project.

Once you've created and opened the project, you can set its properties. These are stored with Eclipse properties. As you saw in Listing 6, the wizard sets a few properties for the XM builder. You should be familiar with those as they are identical to the .xmp file introduced in "Integrating XM and Eclipse."

Last but not least, the wizard populates the project with default directories (the usual src, rules, and publish), a sample XML document, and a simple style sheet. This is just a convenience for the user.


In the pipeline

If you download the source code from the online repository (see Resources), you will find that the plug-in also offers a builder. The builder itself is the topic of my next column.

This article demonstrates that Eclipse gives you, the plug-in developer, enormous freedom to control the user experience. As a result, your plug-in can extend almost any aspect of the user interface.


Resources

Learn

Get products and technologies

  • Download the plug-in from the online repository.

  • Eclipse is an open-source effort to develop an IDE framework. It was initiated by IBM.

  • Try WebSphere Portal, a great solution when publishing more sophisticated portals.

Discuss

About the author

Benoit Marchal

Benoît Marchal is a consultant and writer based in Namur, Belgium. He is the author of XML by Example and other XML books covering the latest features of the XML standard, including the final XML Schema recommendation and the latest developments of XSL. More details are available at www.marchal.com. You can contact Benoît at bmarchal@pineapplesoft.com.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=XML
ArticleID=12202
ArticleTitle=Working XML: Creating a project
publish-date=10012010
author1-email=bmarchal@pineapplesoft.com
author1-email-cc=dwxed@us.ibm.com

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers