Just An Application

November 5, 2009

An Extended NewAnnotation Wizard For Eclipse: Defining The NewWizard Extension

To make Eclipse aware that the fragment contains a wizard we have to define an extension corresponding to the Eclipse defined extension point

    org.eclipse.ui.newWizards

As it says in the documentation for this extension point, which can be found here Platform Plug-in Developer Guide:Reference:Extension Points Reference:org.eclipse.ui.newWizards

This extension point is used to register resource creation wizard extensions. Creation wizards appear as choices within the “New Dialog”, and are typically used to create folders and files.

In the “New Dialog”, wizards are organized into categories which usually reflect a particular problem domain. For instance, a Java oriented plugin may define a category called “Java” which is appropriate for “Class” or “Package” creation wizards. The categories defined by one plug-in can be referenced by other plug-ins using the category attribute. Uncategorized wizards, as well as wizards with invalid category paths, will end up in an “Other” category.

An extension can be defined by simply adding a piece of XML conforming to the schema for the corresponding extension point to the fragment.xml file.

There are two ways to do this. The first is to use the ‘Extensions’ tab of the ‘Fragment’ view which you can bring-ip by double-clicking the MANIFEST.MF file in the ‘Package Explorer’ view.

Extensions

Click Add to bring up the ‘New Extension’ dialog

ExtensionPointSelection

Enter org.eclipse.ui.newWizards in the ‘Extension Pointer filter’ text field. It will appear as the sole element in the list below it. Select it and hit ‘Finish’.

Extensions2

Control-click or right-click the org.eclipse.ui.newWizards element then select New > wizard from the pop-menu.

Extensions3

Then fill in the fields of the resulting editor.

Extensions4

Alternatively you can create a file called fragment.xml in the root directory of the project and put something like this in it.


    <?xml version="1.0" encoding="UTF-8"?>
    <?eclipse version="3.4"?>
    <fragment>
        <extension
            point = "org.eclipse.ui.newWizards">
            <wizard
                name     = "%NewAnnotationType.label"
                icon     = "$nl$/icons/full/etool16/newannotation_wiz.gif"
                category = "org.eclipse.jdt.ui.java"
                id       = "xper.eclipse.plugin.jdt.ui.wizards.NewAnnotationCreationWizard">
                <class 
                    class = "xper.eclipse.plugin.jdt.ui.annotation.NewAnnotationWizard">
                    <parameter 
                        name  = "javatype" 
                        value = "true"/>
                </class>
            </wizard>
        </extension>
    </fragment>

In this case, the name is the same as that of the Eclipse supplied wizard and is in fact a property. The existing value is accessible because the fragment is hosted by the bundle defining. Using the same value however results in two wizards with the same name appearing in menus, etc., which is a bit confusing so I defined a new value in the fragment.properties file.

The fragment.properties file should be in the root directory of the project. In this case it simply contains a single entry.

    NewAnnotationType.label = Annotation [extended]

The icon is that of the Eclipse suppiied wizard and is accessible for the same reason as the name.

The category is the same as that for the Eclipse supplied Java type creation wizards which ensures that the new wizard appears in all the same places that they do.

Note that If you do create the fragment.xml file by hand, and/or a fragment.properties file you will need to add them to the list of files to be included in the binary build, which is configurable from the ‘Build ‘ tab of the ‘Fragment’ view.

Running the fragment using the Eclipse Application configuration results in the new wizard being available. For example, from the drop-down menu of the Java creation button

DropDown


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

November 2, 2009

An Extended NewAnnotation Wizard For Eclipse: Creating The Annotation

By default, for a class inheriting from NewTypeWizardPage, the creation of the Java type is performed by the inherited method

    public void createType(IProgressMonitor monitor)

This method in turn calls

    protected void createTypeMembers(
                       IType            newType,
                       ImportsManager   imports,
                       IProgressMonitor monitor)
                   throws 
                       CoreException

which is documented as a hook method, and it is this method which the example in the documentation overrides.

To create the annotated definition we need to add the referenced Annotation types and Enums to the list of imports and annotate the created Annotation. Both the created type, in this case the Annotation, and the ImportsManager are being passed to the hook method, so it looks as though it should be possible to do what is necessary by overriding this method.

Adding the imports to the ImportsManager is easily done.


        ...

        if (documented)
        {
            imports.addImport(DOCUMENTED_ANNOTATION_TYPE);
        }
        if (inherited)
        {
            imports.addImport(INHERITED_ANNOTATION_TYPE);
        }
        switch (retention)
        {
            case CLASS:
				
                break;
				
                default:
				
                    imports.addImport(RETENTION_ANNOTATION_TYPE);
                    imports.addImport(RETENTION_POLICY_ENUM_TYPE);
        }
        if (targets.size() != 0)
        {
            imports.addImport(TARGET_ANNOTATION_TYPE);
            imports.addImport(ELEMENT_TYPE_ENUM_TYPE);
        }

        ...

with the constants being defined as follows


        private static final String DOCUMENTED_ANNOTATION_TYPE	= "java.lang.annotation.Documented";
	
        private static final String INHERITED_ANNOTATION_TYPE	= "java.lang.annotation.Inherited";
	
        private static final String RETENTION_ANNOTATION_TYPE	= "java.lang.annotation.Retention";
	
        private static final String TARGET_ANNOTATION_TYPE      = "java.lang.annotation.Target";
	
        private static final String ELEMENT_TYPE_ENUM_TYPE      = "java.lang.annotation.ElementType";
	
        private static final String RETENTION_POLICY_ENUM_TYPE	= "java.lang.annotation.RetentionPolicy";

For the Documented and Inherited meta-annotations only the Annotation types themselves need to be imported. In the Retention and Target cases the Enum value types are also imported.

Adding the Annotations themselves to the newly created type turns out to be more difficult. The IType interface extends the IAnnotable amongst others, but none of the methods on IAnnotable or any of the super-interfaces, or on IType itself apparently enable the addition of Annotations.

It is entirely possible that somewhere in the maze of twisty little interfaces there is a way to do so, but I have yet to stumble upon it.

In the end, following a good deal of random experimentation I discovered the


    protected String constructCUContent(
                         ICompilationUnit cu,
                         String           typeContent,
                         String           lineDelimiter)
                     throws 
                         CoreException
 

method on NewTypeWizardPage.

The typeContent argument contains the source of the annotation as created.

Overriding this method modifying the typeContent argument and then invoking the overridden method turns out to have the required effect.


        @Override
        protected String constructCUContent(
                             ICompilationUnit 	theCompilationUnit,
                             String             theTypeContent, 
                             String             theLineDelimiter) 
                         throws 
                             CoreException 
        {	
            StringBuilder builder = new StringBuilder();
		
            if (documented)
            {
                builder.append("@Documented ");
            }
            if (inherited)
            {
                builder.append("@Inherited ");
            }
            switch (retention)
            {
                case CLASS:
			
                    break;
				
                default:
				
                    builder.append("@Retention(RetentionPolicy.");
                    builder.append(retention);
                    builder.append(") ");
            }
		
            int nTargets = targets.size();
		
            if (nTargets != 0)
            {
                builder.append("@Target(");
			
                if (nTargets != 1)
                {
                    boolean first = true;
				
                    builder.append("{");
                    for (ElementType type : targets)
                    {
                        if (!first)
                        {
                            builder.append(", ");
                        }
                        else
                        {
                            first = false;
                        }
                        builder.append("ElementType.");
                        builder.append(type);
                    }
                    builder.append("}");
                }
                else
                {
                    for (ElementType type : targets)
                    {
                        builder.append("ElementType.");
                        builder.append(type);
                    }
                }
                builder.append(") ");
            }
            builder.append(theTypeContent);
            return super.constructCUContent(theCompilationUnit,  builder.toString(), theLineDelimiter);
        }

In CLOS this would have been an :around method. Sigh …


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

November 1, 2009

An Extended NewAnnotation Wizard For Eclipse: Implementing The Wizard Page UI

The UI for a wizard page is created by its implementation of the

    public void createControl(Composite parent);

method defined in the

    org.eclipse.jface.dialogs.IWizardPage

interface.

The NewAnnotationWizardPage implementation of it is as follows


        @Override
        public void createControl(Composite theParent) 
        {
            initializeDialogUnits(theParent);
		
            Composite composite= new Composite(theParent, SWT.NONE);

            composite.setFont(theParent.getFont());
		
            int nColumns = 4;

            GridLayout layout= new GridLayout();
			
            layout.numColumns= nColumns;
            composite.setLayout(layout);

            createContainerControls(composite, nColumns);
            createPackageControls(composite, nColumns);
            createEnclosingTypeControls(composite, nColumns);

            createSeparator(composite, nColumns);

            createTypeNameControls(composite, nColumns);
            createModifierControls(composite, nColumns);
		
            createSeparator(composite, nColumns);
		
            createAnnotationsControls(composite);
		
            createSeparator(composite, nColumns);

            createCommentControls(composite, nColumns);
            enableCommentControl(true);

            setControl(composite);

            Dialog.applyDialogFont(composite);
        }

This is essentially a clone of the same method from the existing Eclipse supplied class with the addition of these three lines.


        ...

        createSeparator(composite, nColumns);
		
        createAnnotationsControls(composite);
		
        createSeparator(composite, nColumns);
		
        ...

The createAnnotationsControls(Composite) method is responsible for the creation of the new UI elements within the page. These are shown below.

NewControls

The text at the top is a Label and is added directly to the parent composite passed in to the call to createControl(Composite), with a horizontal span set to ensure that it is in a row on its own.


        Label label = new Label(theParent, SWT.NONE);
		
        label.setText(Text.WHICH_ANNOTATIONS_TEXT);
		
        GridData labelData = new GridData();
		
        labelData.horizontalSpan = nColumns;
		
        label.setLayoutData(labelData);

There are controls to specify the addition of the four basic meta-annotations

  • Documented
  • Inherited
  • Retention
  • Target

These controls are grouped together into a Composite which is laid out in two columns using a GridLayout


        Composite  group  = new Composite(theParent, SWT.NONE);
        GridLayout layout = new GridLayout();
		
        layout.numColumns = 2;
        group.setLayout(layout);
		
        GridData groupData = new GridData(GridData.FILL_HORIZONTAL);
		
        groupData.horizontalAlignment = SWT.CENTER;
        groupData.horizontalSpan = nColumns - 1;
        group.setLayoutData(groupData);

Both Documented and Inherited are marker annotations: they are either present or not. In each case a checkbox is used to indicate whether they should be present or not.


        Button button = null;
		
        // Documented
	
        label = new Label(group, SWT.NONE);
        label.setText(Text.DOCUMENTED_LABEL);
		
        button = new Button(group, SWT.CHECK);
        button.addSelectionListener(
                   new SelectionAdapter()
                   {
                       public void widgetSelected(SelectionEvent theEvent)
                       {
                           documented = ((Button)(theEvent.widget)).getSelection();
                       }
                   });
		
        // Inherited
		
        label = new Label(group, SWT.NONE);
        label.setText(Text.INHERITED_LABEL);
		
        button = new Button(group, SWT.CHECK);
        button.addSelectionListener(
                   new SelectionAdapter()
                   {
                       public void widgetSelected(SelectionEvent theEvent)
                       {
                           inherited = ((Button)(theEvent.widget)).getSelection();
                       }
                   });

The Retention annotation has value of type RetentionPolicy which is an Enum with a choice of three values. These are represented by a group of radio buttons. The currently selected value is represented by the corresponding value of RetentionPolicy which is stored in the retention instance variable.


        // Retention
		
        label = new Label(group, SWT.NONE);
        label.setText(Text.RETENTION_LABEL);
		
        Composite  retentionGroup        = new Composite(group, SWT.NONE);
        GridLayout retentionGroupLayout  = new GridLayout();
		
        retentionGroupLayout.numColumns   = N_RETENTION_GROUP_COLUMNS;
        retentionGroup.setLayout(retentionGroupLayout);
		
        Listener listener = new Listener()
                            {
                                @Override
                                public void handleEvent(Event theEvent) 
                                {
                                    Button button = (Button)(theEvent.widget);
									
                                    if (button.getSelection())
                                    {
                                        retention = (RetentionPolicy)button.getData();
                                    }
                                }
                            };
		
        for (String name : sortedNames(RetentionPolicy.class))
        {
            label = new Label(retentionGroup, SWT.NONE);
            label.setText(name);
		
            button = new Button(retentionGroup, SWT.RADIO);
            button.addListener(SWT.Selection, listener);
            button.setData(Enum.valueOf(RetentionPolicy.class, name));
            if (RetentionPolicy.CLASS.name().equals(name))
            {
                button.setSelection(true);
            }
        }

The sortedNames method is a utility method which returns the names of an Enum’s values in alphabetical order. It is possible to obtain a set containing all the values of a given Enum but these are in the order they appear in the Enum definition, which is not necessarily alphabetical.


        private <E extends Enum<E>> Iterable<String> sortedNames(Class<E> theEnumClass)
        {
            List<String> names = new ArrayList<String>();
		
            for (Enum<E> e : EnumSet.allOf(theEnumClass))
            {
                names.add(e.name());
            }
            Collections.sort(names);
            return names;
        }

The Target annotation can have multiple values of the Enum type ElementType. These are represented by a group of checkboxes. The currently selected values are held in the instance variable targets which is of type EnumSet<ElementType>.


        // Targets
		
        label = new Label(group, SWT.NONE);
        label.setText(Text.TARGETS_LABEL);
		
        GridData targetsData = new GridData();
		
        targetsData.verticalAlignment = SWT.TOP;
        label.setLayoutData(targetsData);
		
        Composite targetsGroup       = new Composite(group, SWT.NONE);
        RowLayout targetsGroupLayout = new RowLayout(SWT.VERTICAL);
		
        targetsGroupLayout.marginLeft = 0;
        targetsGroupLayout.marginTop  = 0;
        targetsGroup.setLayout(targetsGroupLayout);
		
        listener = new Listener()
        {
            @Override
            public void handleEvent(Event theEvent) 
            {
                Button      button = (Button)(theEvent.widget);
                ElementType type   = (ElementType)button.getData();
				
                if (button.getSelection())
                {
                    targets.add(type);
                }
                else
                {
                    targets.remove(type);
                }
            }
        };
		
        for (String name : sortedNames(ElementType.class))
        {
            button = new Button(targetsGroup, SWT.CHECK);
            button.addListener(SWT.Selection, listener);
            button.setData(Enum.valueOf(ElementType.class, name));
            button.setText(name);
        }



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

October 30, 2009

An Extended NewAnnotation Wizard For Eclipse: Implementing A Wizard Page

Filed under: Eclipse, Eclipse Plugins, Eclipse Wizards, Java — Tags: , , , — Simon Lewis @ 12:41 pm

The new wizard page is implemented by the class

    xper.eclipse.plugin.jdt.ui.annotation.NewAnnotationWizardPage

which sub-classes

    org.eclipse.jdt.ui.wizards.NewTypeWizardPage

following the example in JDT Plug-in Developer Guide:Programmer’s Guide:JDT UI: Java wizard pages

The constructor is based on that from the equivalent Eclipse supplied class as follows


        NewAnnotationWizardPage() 
        {
            super(ANNOTATION_TYPE, "NewAnnotationWizardPage");
            setTitle(NewWizardMessages.NewAnnotationWizardPage_title);
            setDescription(NewWizardMessages.NewAnnotationWizardPage_description);
            retention = RetentionPolicy.CLASS;
            targets   = EnumSet.noneOf(ElementType.class);
        }

as is the initialization method

        void init(IStructuredSelection theSelection) 
        {
            IJavaElement element= getInitialJavaElement(theSelection);

            initContainerPage(element);
            initTypePage(element);
            retention = RetentionPolicy.CLASS;
            targets.clear();
            updateStatus();
        }

The initContainerPage(IJavaElement) method is inherited from

    org.eclipse.jdt.ui.wizards.NewContainerWizardPage

which is the super-class of NewTypeWizardPage.

The initTypePage(IJavaElement) method is inherited from NewTypeWizardPage.

You might expect that this method would invoke initContainerPage(IJavaElement) itself but apparently not.

The updateStatus() method is as follows.


        private void updateStatus()
        {
            updateStatus(
                new IStatus[] 
                {
                    fContainerStatus,
                    isEnclosingTypeSelected() 
                        ? 
                        fEnclosingTypeStatus 
                        : 
                        fPackageStatus,
                    fTypeNameStatus,
                    fModifierStatus,
                });
        }

It is responsible for collecting together the statuses of all the data required to construct the Annotation
and passing them to the updateStatus(IStatus[]) method inherited from the

    org.eclipse.jdt.ui.wizards.NewElementWizardPage

class.

This method then updates the status of the wizard page as appropriate.

For example, if all the necessary data is present and there are no problems with it then the ‘Finish’ or ‘Next’ button will be enabled.

Alternatively if, for example, a name for the Annotation has been entered and then deleted then fTypeNameStatus has an IStatus value with a severity of ERROR and the message

    Type name is empty.

which is duly displayed by the wizard as shown below.

TypeNameIsEmpty

Since an Annotation can legally be defined without any annotation this method is the same as that of the equivalent Eclipse supplied class.


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

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

October 29, 2009

An Extended NewAnnotation Wizard For Eclipse: Getting Started

Because I wanted to re-use the existing Eclipse NewAnnotation wizard code, if at all possible, I decided to create a fragment hosted by the bundle containing the code for the Eclipse Java type creation wizards, rather than a stand-alone bundle. Note that Eclipse uses the term ‘plug-in’, but an Eclipse ‘plug-in’ is an OSGi bundle with some added stuff, and I’m going to stick to the term bundle.

To do this select ‘New’ from the ‘File’ menu on the toolbar, ‘Project’ from the resulting sub-menu and ‘Fragment Project’ from the ‘Plug-in Development’ section of the resulting dialog

NewProject

Hit ‘Next’ and you will get the first page of the ‘New Fragment Project’ wizard

FragmentProject1

Fill in the Project Name and hit ‘Next’

FragmentProject2Blank

The Host Plug-in (bundle) section needs to be filled-in, so hit ‘Browse’ and you will get the ‘Plug-in Selection’ dialog show below

PluginSelectionBlank

We are actually interested in the code in the package

       org.eclipse.jdt.ui.wizards

but which bundle is it in ?

The mapping of packages to JDT bundles can be found in the JDT Plug-ins Map which shows that we are after the

       org.eclipse.jdt.ui

bundle.

Entering this is in the text field at the top gets us two matches

PluginSelection

Picking the top-most one and hitting ‘OK’ gets us back to the second page

FragmentProject2

That’s it. Hit ‘Finish’, respond to the resulting dialog about opening the associated perspective and its done.

Not that it does currently does anything but the resulting fragment can be ‘run’ by selecting the ‘run’ button from the toolbar and then selecting ‘Eclipse Application’ from the ‘Run As’ sub-menu, unless you are running Eclipse on Snow Leopard, that is, in which case you may get an error dialog instead, and a log containing the following


!ENTRY org.eclipse.osgi 4 0 2009-10-29 21:13:30.206
!MESSAGE Application error
!STACK 1
java.lang.UnsatisfiedLinkError: Cannot load 32-bit SWT libraries on 64-bit JVM
	at org.eclipse.swt.internal.Library.loadLibrary(Library.java:182)
	at org.eclipse.swt.internal.Library.loadLibrary(Library.java:159)
	at org.eclipse.swt.internal.C.(C.java:21)
	at org.eclipse.swt.internal.cocoa.NSThread.isMainThread(NSThread.java:33)
	at org.eclipse.swt.graphics.Device.(Device.java:116)
	at org.eclipse.swt.widgets.Display.(Display.java:628)
	at org.eclipse.swt.widgets.Display.(Display.java:619)
	at org.eclipse.ui.internal.Workbench.createDisplay(Workbench.java:532)
	at org.eclipse.ui.PlatformUI.createDisplay(PlatformUI.java:161)
	at org.eclipse.ui.internal.ide.application.IDEApplication.createDisplay(IDEApplication.java:143)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:88)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:194)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:368)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:559)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:514)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1311)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1287)

which is a bit of a pain

Fortunately it is easily fixed.

Bring up the ‘Run Configurations’ dialog, using ‘Run Configurations …’ from the menu on the ‘run’ button for example, select ‘Eclipse Application’ then select the ‘Arguments’ tab.

In the ‘Program arguments’ text box at the top prepend the argument

       -d32

as shown below. This tells the VM not to mess about with all that 64-bit stuff, or something like that.

RunConfigurations

Try ‘running’ the fragment again and you should now get a second copy of Eclipse uncannily similar to the one you are already running.


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

An Extended NewAnnotation Wizard For Eclipse

Something you cannot currently do with any of the Eclipse Java type creation wizards is add annotations. This is not a particularly big deal, you can always add them later using the editor, unless you happen to be defining a lot of new annotations which are themselves annotated with one or more of the built-in meta-annotations

in which case it would be quite handy to be able to tick some boxes in the wizard and have them appear auto-magically

Here’s the wizard as implemented by Eclipse

AnnotationWizard

Anyway, because I have been defining quite a few new annotations and was getting quite bored with adding the meta-annotations by hand I thought I would have a go at customizing the default wizard and adding the features I wanted.

It turned out to be a bit more involved than I had expected, but it can be done, and here it is.

NewAnnotationWizard

Not the world’s greatest UI design for sure, but it does the job.


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

Create a free website or blog at WordPress.com.

%d bloggers like this: