How to implement a JFace Wizard?
Create a WizardPage
subclass for every step of the wizard, for example:
publicclassExampleWizardPageextendsWizardPage{publicExampleWizardPage(){super("wizardPage");setTitle("Wizard Page 1");setDescription("Example wizard page");}publicvoidcreateControl(Compositeparent){Compositecontainer=newComposite(parent,SWT.NULL);setControl(container);container.setLayout(newGridLayout(2,false));LabellblName=newLabel(container,SWT.NONE);lblName.setText("Name:");Texttext=newText(container,SWT.BORDER);text.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false,1,1));}}
Create a Wizard
class for the whole wizard:
publicclassExampleWizardextendsWizard{@OverridepublicvoidaddPages(){addPage(newExampleWizardPage());addPage(newExampleWizardPage());}@OverridepublicbooleanperformFinish(){// Handle finishing the Wizard herereturntrue;}}
Use a WizardDialog
to display the wizard:
ExampleWizardwizard=newExampleWizard();WizardDialogdialog=newWizardDialog(parentShell,wizard);dialog.open();
How to use values from preceding pages?
If you need to access values from a preceding page, the straightforward way would be to pass through the previous page or use WizardPage#getPreviousPage()
. I recommend to create a value object that contains all the input from the different wizard pages instead. Please note that updating UI values in createControl
doesn’t work because createControl
will be called only once in advance. The only place to update the UI of a wizard page before it is shown is in WizardPage#setVisible
. For example:
publicclassExampleValues{publicStringvalue="";publicStringgetValue(){returnvalue;}publicvoidsetValue(Stringvalue){this.value=value;}}publicclassExampleWizardextendsWizard{privateExampleValuesvalues=newExampleValues();@OverridepublicvoidaddPages(){addPage(newExampleWizardPage(values));addPage(newExampleWizardPage(values));}@OverridepublicbooleanperformFinish(){// Handle finishing the Wizard using values herereturntrue;}}publicclassExampleWizardPageextendsWizardPage{privateExampleValuesvalues;privateTexttext;publicExampleWizardPage(ExampleValuesvalues){super("wizardPage");setTitle("Wizard Page 1");setDescription("Example wizard page");this.values=values;}publicvoidcreateControl(Compositeparent){text=newText(container,SWT.BORDER);setControl(text);text.addModifyListener(newModifyListener(){@OverridepublicvoidmodifyText(ModifyEvente){values.setValue(text.getText());}});}@OverridepublicvoidsetVisible(booleanvisible){super.setVisible(visible);if(visible){text.setText(values.getValue());}}}
How to decide which page to show depending on values from preceding pages?
WizardPage
has a method getNextPage()
that can be overwritten to decide dynamically which page should be shown next. The page has to be added to the Wizard
in advance, so this is only suitable to skip pages.
If you want to build wizards with a more dynamic/branched page flow, I recommend to define a strategy which decides which page is next in Wizard#getNextPage
. For example:
publicclassExampleWizardextendsWizard{privateExampleValuesvalues=newExampleValues();privateIWizardPagepage1=newExampleWizardPage("Page 1",values);privateIWizardPagepage2=newExampleWizardPage("Page 2",values);privateIWizardPagespecialPage=newExampleWizardPage("Special Page",values);@OverridepublicvoidaddPages(){addPage(page1);addPage(page2);addPage(specialPage);}@OverridepublicIWizardPagegetNextPage(IWizardPagecurrentPage){if(values.getValue().equals("special")){returnspecialPage;}if(currentPage==page1){returnpage2;}returnnull;}}