Integrating a Progress Bar into a Wizard
- by Geertjan
Normally, when you create a wizard, as described here, and you have your own iterator, you'll have a class signature like this:
public final class MyWizardWizardIterator
implements WizardDescriptor.InstantiatingIterator<WizardDescriptor> {
Let's now imagine that you've got some kind of long running process your wizard needs to perform. Maybe the wizard needs to connect to something, which could take some time.
Start by adding a new dependency on the Progress API, which gives you the classes that access the NetBeans Platform's progress functionality.
Now all we need to do is change the class signature very slightly:
public final class MyWizardWizardIterator
implements WizardDescriptor.ProgressInstantiatingIterator<WizardDescriptor> {
Take a look at the part of the signature above that is highlighted. I.e., use WizardDescriptor.ProgressInstantiatingIterator instead of WizardDescriptor.InstantiatingIterator.
Now you will need to implement a new instantiate method, one that receives a ProgressHandle. The other instantiate method, i.e., the one that already existed, should never be accessed anymore, and so you can add an assert to that effect:
@Override
public Set<?> instantiate() throws IOException {
throw new AssertionError("instantiate(ProgressHandle) " //NOI18N
+ "should have been called"); //NOI18N
}
@Override
public Set instantiate(ProgressHandle ph) throws IOException {
return Collections.emptySet();
}
OK. Let's now add some code to make our progress bar work:
@Override
public Set instantiate(ProgressHandle ph) throws IOException {
ph.start();
ph.progress("Processing...");
try {
//Simulate some long process:
Thread.sleep(2500);
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
}
ph.finish();
return Collections.emptySet();
}
And, maybe even more impressive, you can also do this:
@Override
public Set instantiate(ProgressHandle ph) throws IOException {
ph.start(1000);
ph.progress("Processing...");
try {
//Simulate some long process:
ph.progress("1/4 complete...", 250);
Thread.sleep(2500);
ph.progress("1/2 complete...", 500);
Thread.sleep(5000);
ph.progress("3/4 complete...", 750);
Thread.sleep(7500);
ph.progress("Complete...", 1000);
Thread.sleep(1000);
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
}
ph.finish();
return Collections.emptySet();
}
The screenshots above show you what you should see when the Finish button is clicked in each case.