开发者

Allow a Wizard to run only from an existing project

I am doing an Import Wizard for an Eclipse plugin.

It should be allowed only if the selection is an IProject and display an error (and close itself) otherwise.

Do you how this is feasible?

I tried using getShell().close() and getContainer().getShell().close() from my OwnWizard.init(...) method if the selection is not an IProject, but I get a NullPointerException regarding getShell() (it appears it's not yet valid).

I tried with this snippet:

public class GetPackWizard extends Wizard implements IImportWizard {
private IProject project = null;
// ...
@Override
public void addPages() {
    logger.trace("Adding pages.");
    addPage(new SelectPackagesWizardPage(project));
    versionsPage = new SelectVersionsWizardPage(project);
    addPage(versionsPage);
}

//...
@Override
public void init(IWorkbench workbench, IStructuredSelection selection) {
    project = null;
    if (selection.size() > 0) {
        Object obj = selection.getFirstElement();
        if (obj instanceof IResource) {
            IResource resource = (IResource)obj;
                if (obj instanceof IProject)
                    project = (IProject)obj;
                else
                    project = resource.getProject();
        }
    }

    if (project == null) {
        MessageDialog.openError(
            getShell(),
            "GetPack Wizard", 
            "You must run this wizard from a project."
        );
        performCancel();
    }
}

Though the Wizard closes, the addPages() method is开发者_StackOverflow中文版 still called, thus leading to some NullPointerException (since the project field is null).

Is there a way I can prevent that from happening? It could be great if I don't have to reimplement the createControls() Wizard method :)

Thanks for your help,

Best regards,

Greg*.


Since you are talking about closing the shell and etc, therefore I am assuming that you have already figured out selection is an IProject and display an error.

Closing the Wizard:

All the standard wizard implements the abstract org.eclipse.jface.wizard.Wizard. If you want to close it then simply call its performCancel() method. (I did not know you are calling getShell().close() in init())


Update:

The reason is simple. When you select a particular wizard in the import wizard and press next then the following method is called from the org.eclipse.jface.wizard.WizardSelectionPage

public IWizardPage getNextPage() 
{
    if (selectedNode == null) {
        return null;
    }

    boolean isCreated = selectedNode.isContentCreated();

    IWizard wizard = selectedNode.getWizard(); // THIS WILL CALL THE INIT

    if (wizard == null) {
        setSelectedNode(null);
        return null;
    }

    if (!isCreated) {
        // Allow the wizard to create its pages
        wizard.addPages();              // THIS IS ADDING THE EXTRA PAGES
    }

    return wizard.getStartingPage();
}

As you can see the IselectedNode.getWizard(); statement comes earlier than wizard.addPages(); therefore even though you have identified that the selection is not IProject and called performCancel() (which won't have any effect as dialog-content-area itself is not created) it will still go on to wizard.addPages();.

As you have already noticed that getShell() in the init() method will return null. To solve this issue (unfortunately) you have to override the public void createPageControls(Composite pageContainer), but don't worry the change required is minimal:

public void createPageControls(Composite pageContainer) {
    if(flag){
        getShell().close();
        return;
    }
    super.createPageControls(pageContainer);
}

For reference see the full code below:

public class MyImportWizard extends Wizard implements IImportWizard {

    private IProject project = null;

    private boolean flag = false;

    public void addPages() {
        if(!flag)
            System.out.println("Hello");
    }

    public void createPageControls(Composite pageContainer) {
        if(flag){
            getShell().close();
            return;
        }
        super.createPageControls(pageContainer);
    }

    public void init(IWorkbench workbench, IStructuredSelection selection) 
    {
        project = null;
        if (selection.size() > 0) {
            Object obj = selection.getFirstElement();
            if (obj instanceof IResource) {
                IResource resource = (IResource)obj;
                if (obj instanceof IProject)
                    project = (IProject)obj;
                else
                    project = resource.getProject();
            }
        }

        if (project == null) {
            MessageDialog.openError(
                    getShell(),
                    "GetPack Wizard", 
                    "You must run this wizard from a project."
            );
            flag = true;
        }
    }

    @Override
    public boolean performFinish() {
        return true;
    }
}

Give it a try, meanwhile I will see whether it can be done in a more sophisticated manner.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜