Multi-page wizards

If your wizard implements a complex task, you may want to use more than one page to obtain information from the user.

In general, the implementation pattern is the same as for a single page wizard.

When you design a wizard, it's good practice to put all the required information on the first page if possible. This way, the user does not have to traverse the entire set of pages in order to finish the task.  Optional information can go on subsequent pages.

When a page requires input from the user before it can be considered complete, use setPageComplete(false) to signify that it is not complete. As the page receives events from its controls, it rechecks to see if the page is complete. Once the required input is provided, setPageComplete(true) signals completion.

The Wizard class handles the logic required to enable and disable the Finish button according to the completion state of the pages.  The Finish button is only enabled for a wizard when each of its pages have set its completion state to true.

Validation and page control

The classes WizardNewFileCreationPage and CreateReadme1 show a common pattern for implementing page validation.

WizardNewFileCreationPage defines a common event handler for all SWT events which validates the page. This means the page will be validated whenever an event is received from a widget to which the page added a listener.

   public void handleEvent(Event event) {
      setPageComplete(validatePage());
   }

Once the ReadmeCreationPage creates its controls, it sets the state of the page using validatePage.

   public void createControl(Composite parent) {
      super.createControl(parent);
      // create controls, add listeners, and layout the page
      ...
      // sample section generation checkboxes
      sectionCheckbox = new Button(group,SWT.CHECK);
      sectionCheckbox.setText(MessageUtil.getString("Generate_sample_section_titles"));
      sectionCheckbox.setSelection(true);
      sectionCheckbox.addListener(SWT.Selection,this);

      subsectionCheckbox = new Button(group,SWT.CHECK);
      subsectionCheckbox.setText(MessageUtil.getString("Generate_sample_subsection_titles"));
      subsectionCheckbox.setSelection(true);
      subsectionCheckbox.addListener(SWT.Selection,this);
      ...
      setPageComplete(validatePage());
   }

Using this pattern, a wizard page can put all of its page validation code in one method, validatePage(). This method determines the initial state of the page and recalculates the state any time it receives an event from a widget on its page.

Since we added a listener to the section checkbox, we will recompute the valid state of the page whenever that checkbox receives a selection event. Note that the page's handleEvent method must call super to ensure that the inherited page validation behavior occurs in addition to any specific event handling for this page.

   public void handleEvent(Event e) {
      Widget source = e.widget;
      if (source == sectionCheckbox) {
         if (!sectionCheckbox.getSelection())
            subsectionCheckbox.setSelection(false);
         subsectionCheckbox.setEnabled(sectionCheckbox.getSelection());
      }
      super.handleEvent(e);
   }