Howto Implement Wizards Steps

Author: Dafe Simonek
$Revision: 1.1.1.1 $
$Date: 2009/10/29 16:50:15 $
Document history: available in CVS

There are two common ways to construct wizard steps. Both techinues are based on implementing WizardDescriptor.Panel interface, implementation of java.awt.Component getComponent() method makes the difference.

Index:

1. Constructing each step as two separate java classes (recommended)

This technique separates UI from the data. First class is implementation of WizardDescriptor.Panel interface and represents data of wizard step. Should be kept lightweight, managing only data.
Second, separate class is subclass of JPanel and represents uer interface of wizard step.
The WizardDescriptor.Panel subclass should reference the JPanel subclass, instantiate and return an instance of that class the first time its java.awt.Component getComponent() method is called. This is the safest, performant and also the preferred way to construct wizard steps. Please see Performance problems explanation section for details.

Example:

2. Constructing each step as one java class

Constrcut JPanel subclass that implements WizardDescriptor.Panel interface. Implement java.awt.Component getComponent() method of WizardDescriptor.Panel by just returning this.
Such technique is often more convenient to write because it puts all the step code in a single source file, but the technique has a drawbacks you need to be aware of:
  • Your step class must define an isValid method, because that is what tells system whether the Next button should be enabled. But implementing that method also over-rides the superclass method Component.isValid. If this accidental override causes you a problem, then you must structure the steps of that wizard using technique 1., described above.
  • System will not be able to optimize the instantiation of your steps (please see Performance problems explanation to find out what it means).
    So you must handle optimization yourself in case your wizard takes long to appear on screen or takes long to react on Next button.

3. Changing from technique 2 to technique 1

You should try to refactor your code to conform to technique 1 whenever:
  • You need to override both java.awt.Component.isValid and WizardDescriptor.Panel.isValid methods.
  • Invocation time of your wizard is greater then 1 second or pauses between pressed button (Next, Cancel, Finish) and visible reaction of the system is greater then 0,5 second.
    Please read details of how to Measure UI Responsiveness and keep in mind that you should use or simulate computer which meets Netbeans system requirements
Example:

In following example, class IDESettingsPanel.java was disjoined into lightweight IDESettingsWizardPanel.java and modified reduced IDESettingsPanel.java, which now serves only as UI component of wizard panel.

If you assured that your wizard wouldn't fall into problems specified above, you can continue using technique 2 as well.

4. Performance problems explanation

Custom wizard panels often implements interface org.netbeans.WizardDescriptor.Panel and at the same time extend java.awt.Component and return this from java.awt.Component getComponent() method (=technique 2). This can lead to responsiveness degradation, because usually all such panels, including their UI components are fully created and initialized before wizard is even shown for the first time, which is obviously wrong.
It's partially because nearly all wizards use default support for wizard iterator, org.netbeans.WizardDescriptor.ArrayIterator. Iterator instantiates all wizard panels immediatelly, but these panels are also UI components, so it in fact means creation of all UI components of all panels.

You may think that by implementing your own org.netbeans.WizardDescriptor.Iterator problem is solved, but it isn't quite right. Better technique is to make org.netbeans.WizardDescriptor.Panel implementation as lightweight as possible and defer all UI initialization to java.awt.Component getComponent() method. Main reason is that system then can decide when is the right time to fully initialize individual wizard panels. System can use pre-initialization to minimize pauses when user presses "Next" button, system can perform initialization in background thread when user activity is low and have next panel ready when user presses "Next" button.

Sometimes even the actual painting of UI of wizard step (especially fist one) may be too slow. In such situation technique called Post-initialization of visible components may help you.


Please send comments to nbdev.

Project Features

About this Project

Performance was started in November 2009, is owned by tpavek, and has 81 members.
By use of this website, you agree to the NetBeans Policies and Terms of Use (revision 20160708.bf2ac18). © 2014, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo
 
 
Close
loading
Please Confirm
Close