允许向导仅从现有项目运行

时间:2011-05-04 14:57:29

标签: java eclipse jface

我正在为Eclipse插件执行导入向导。

仅当选择是IProject并且显示错误(并自行关闭)时才允许它。

你知道这是可行的吗?

如果选择不是getShell().close(),我尝试使用我的getContainer().getShell().close()方法中的OwnWizard.init(...)IProject,但我得NullPointerException getShell() (看来它还没有效果。)

我尝试使用此代码段:

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();
    }
}

虽然向导关闭,但仍会调用addPages()方法,从而导致某些NullPointerException(因为project字段为空)。

有没有办法阻止这种情况发生?如果我不必重新实现createControls()向导方法,那可能会很棒。)

感谢您的帮助,

致以最诚挚的问候,

格雷格*

1 个答案:

答案 0 :(得分:2)

由于您正在谈论关闭shell等,因此我假设您已经确定 选择是一个IProject并显示错误

关闭向导:

所有标准向导都实现了抽象org.eclipse.jface.wizard.Wizard。如果你想关闭它,那么只需调用它的performCancel()方法。(我不知道你在getShell().close()中呼叫init()

<小时/> 的更新

原因很简单。当您在import向导中选择特定向导并按next时,将从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();
}

正如您所看到的,IselectedNode.getWizard();语句早于wizard.addPages();,因此即使您已确定选择不是IProject并且名为performCancel()(也不会如果没有创建对话框内容区域本身有任何效果,它仍将继续wizard.addPages();

您已经注意到getShell()方法中的init()将返回 null 。要解决此问题(不幸的是),您必须覆盖public void createPageControls(Composite pageContainer),但不要担心所需的更改很少:

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

供参考,请参阅以下完整代码:

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;
    }
}

尝试一下,同时我将看到它是否可以以更复杂的方式完成。