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 (I did not know you are calling org.eclipse.jface.wizard.Wizard
. If you want to close it then simply call its performCancel()
method.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.
精彩评论