Just An Application

October 30, 2009

An Extended NewAnnotation Wizard For Eclipse: Implementing A New Wizard

An Eclipse wizard comprises a wizard object and one or more pages. In the case of the Eclipse supplied NewAnnotation wizard the wizard object is an instance of

    org.eclipse.jdt.internal.ui.wizards.NewAnnotationCreationWizard

which has a single page which is an instance of

    org.eclipse.jdt.ui.wizards.NewAnnotationWizardPage

Neither of these classes were designed to be extensible, and certainly not dynamically.

As it states in the documentation for the class NewAnnotationWizardPage

Note: This class is not intended to be subclassed, but clients can instantiate.

so we need a new wizard page, and the NewAnnotationCreationWizard default constructor is hard-wired to use an instance of NewAnnotationWizardPage so we need a new wizard object as well.

The class

    org.eclipse.jdt.ui.wizards.NewTypeWizardPage

is supplied for use as a base class for new wizard pages for creating new Java type instances, but what about the wizard object itself ? The NewAnnotationCreationWizard class is undocumented and is in a package with ‘internal’ in its name, as is its base class

	org.eclipse.jdt.internal.ui.wizards.NewElementWizard

so it is probably not intended for use by other bundles, but a fragment is effectively part of its host bundle, it uses the same class loader for example, so the classes in internal packages are at least visible to it.

As an aside, looking at the manifest of the org.eclipse.jdt.ui bundle shows the following entry in the Export-Package header

    org.eclipse.jdt.internal.ui.wizards;x-friends:="org.eclipse.jdt.junit, org.eclipse.jdt.apt.ui"

so the package is being exported but qualified using the Eclipse specific x-friends directive which is used

to specify a list of bundles which are allowed access to the package

so the package is being exported, but only for use by those two bundles.

As an aside on the aside, the IDE will allow a reference to a type in the package from an arbitrary bundle but there is an associated warning.

Anyway, from within a fragment hosted by the org.eclipse.jdt.ui bundle we can access any class, irrespective of the export status of its containing package. ‘tho the standard Java access controls still apply obviously. This is handy since it means we can effectively clone the NewAnnotationCreationWizard class as follows

Note that the NewAnnotationWizardPage class being referenced is the new wizard page class not the Eclipse supplied one.


package xper.eclipse.plugin.jdt.ui.annotation;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.JavaPluginImages;
import org.eclipse.jdt.internal.ui.wizards.NewElementWizard;
import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;

public final class NewAnnotationWizard 
                   extends
                       NewElementWizard
{
    public NewAnnotationWizard()
    {
        setDefaultPageImageDescriptor(JavaPluginImages.DESC_WIZBAN_NEWANNOT);
        setDialogSettings(JavaPlugin.getDefault().getDialogSettings());
        setWindowTitle(NewWizardMessages.NewAnnotationCreationWizard_title);
    }
	
    //
	
    @Override
    public void addPages() 
    {
        super.addPages();
        if (page == null) 
        {
            page = new NewAnnotationWizardPage();
            page.init(getSelection());
        }
        addPage(page);
    }
	
	
    @Override
    public IJavaElement getCreatedElement() 
    {
        return page.getCreatedType();
    }
	
    @Override
    public boolean performFinish() 
    {
        warnAboutTypeCommentDeprecation();
	
        boolean result= super.performFinish();
		
        if (result) 
        {
            IResource resource= page.getModifiedResource();
			
            if (resource != null) 
            {
                selectAndReveal(resource);
                openResource((IFile)resource);
            }
        }
        return result;
    }

    //
	
    @Override
    protected void finishPage(IProgressMonitor theMonitor)
                   throws 
                       CoreException,
                       InterruptedException 
				        
    {
        page.createType(theMonitor);
    }
	
    //
	
    private NewAnnotationWizardPage	page;
}



Copyright (c) 2009 By Simon Lewis. All Rights Reserved

Advertisements

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Create a free website or blog at WordPress.com.

%d bloggers like this: