JFace Wizard FAQ

How to implement a JFace Wizard?

Create a WizardPage subclass for every step of the wizard, for example:

public class ExampleWizardPage extends WizardPage {

    public ExampleWizardPage() {
        super("wizardPage");
        setTitle("Wizard Page 1");
        setDescription("Example wizard page");
    }

    public void createControl(Composite parent) {
        Composite container = new Composite(parent, SWT.NULL);
        setControl(container);

        container.setLayout(new GridLayout(2, false));

        Label lblName = new Label(container, SWT.NONE);
        lblName.setText("Name:");

        Text text = new Text(container, SWT.BORDER);
        text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
    }

}

Create a Wizard class for the whole wizard:

public class ExampleWizard extends Wizard {

    @Override
    public void addPages() {
        addPage(new ExampleWizardPage());
        addPage(new ExampleWizardPage());
    }

    @Override
    public boolean performFinish() {
        // Handle finishing the Wizard here
        return true;
    }

}

Use a WizardDialog to display the wizard:

ExampleWizard wizard = new ExampleWizard();
WizardDialog dialog = new WizardDialog(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:

public class ExampleValues {

    public String value = "";

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

public class ExampleWizard extends Wizard {

    private ExampleValues values = new ExampleValues();

    @Override
    public void addPages() {
        addPage(new ExampleWizardPage(values));
        addPage(new ExampleWizardPage(values));
    }

    @Override
    public boolean performFinish() {
        // Handle finishing the Wizard using values here
        return true;
    }

}

public class ExampleWizardPage extends WizardPage {

    private ExampleValues values;
    private Text text;

    public ExampleWizardPage(ExampleValues values) {
        super("wizardPage");
        setTitle("Wizard Page 1");
        setDescription("Example wizard page");
        this.values = values;
    }

    public void createControl(Composite parent) {
        text = new Text(container, SWT.BORDER);
        setControl(text);
        text.addModifyListener(new ModifyListener() {

            @Override
            public void modifyText(ModifyEvent e) {
                values.setValue(text.getText());
            }

        });
    }

    @Override
    public void setVisible(boolean visible) {
        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:

public class ExampleWizard extends Wizard {

    private ExampleValues values = new ExampleValues();
    private IWizardPage page1 = new ExampleWizardPage("Page 1", values);
    private IWizardPage page2 = new ExampleWizardPage("Page 2", values);
    private IWizardPage specialPage = new ExampleWizardPage("Special Page", values);

    @Override
    public void addPages() {
        addPage(page1);
        addPage(page2);
        addPage(specialPage);
    }

    @Override
    public IWizardPage getNextPage(IWizardPage currentPage) {
        if (values.getValue().equals("special")) {
            return specialPage;
        }
        if (currentPage == page1) {
            return page2;
        }
        return null;
    }

}

Apps

website screenshot mac os x

About the author

Ralf Ebert Ralf Ebert is an independent software developer and trainer for Mac OS X and iOS. He makes the Page Layers and Straight ahead apps and conducts iOS trainings and Git trainings in Germany.