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

发布于 2024-11-05 01:46:25 字数 1642 浏览 1 评论 0原文

我正在为 Eclipse 插件做一个导入向导。

仅当选择的是 IProject 时才应允许,否则显示错误(并自行关闭)。

你知道这如何可行吗?

我尝试使用 OwnWizard.init(...)< 中的 getShell().close()getContainer().getShell().close() /code> 方法,如果选择的不是 IProject,但我收到一个关于 getShell()NullPointerException (看起来它尚未有效) 。

我尝试使用以下代码片段:

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() 向导方法,那就太好了:)

感谢您的帮助,

谨致问候,

Greg*。

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 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*.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清君侧 2024-11-12 01:46:25

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

关闭向导:

所有标准向导都实现抽象org.eclipse.jface.wizard.Wizard。如果您想关闭它,只需调用其 performCancel() 方法即可。 (我不知道您在 getShell().close() 中调用 getShell().close()代码>init())


Update:

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

正如您所看到的< code>IselectedNode.getWizard(); 语句早于 wizard.addPages(); 因此,即使您已确定该选择不是 IProject 并且被调用performCancel()(不会产生任何效果,因为dialog-content-area本身没有创建)它仍然会继续到wizard.addPages();

您已经注意到,init() 方法中的 getShell() 将返回 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;
    }
}

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文