X

Geertjan's Blog

  • October 2, 2005

How Wizards Work (Part 3): Your First Wizard

Geertjan Wielenga
Product Manager
The wizard described below consists of one panel. Therefore, it could not possibly be simpler. However, creating this panel shows you some of the central concepts involved in the creation of wizards using the NetBeans APIs. The good thing is that most of the initial stages are wizard-driven; the bad part is that the rest of it is a little tricky. Most of the reason for this is that each panel is split over two classes, for good reasons (described here), but it doesn't make your life as a programmer much easier. Still, it's great for performance, as the comments in the Wizard wizard's generated code tells you—"if the wizard is created but never displayed, or not all panels are displayed, it is better to create only those which really need to be visible". So, each step in the wizard consists of a Visual component (which consists of a 'Design' part and a 'Source' part), subclassing JPanel and a Wizard component, subclassing the NetBeans API's WizardDescriptor.Panel. The WizardDescriptor.Panel subclass references the JPanel subclass, instantiates and returns an instance of that class the first time its java.awt.Component getComponent() method is called.

The one-panel wizard created below lets you specify a preferred job location. Here are the steps to take:

  1. Create a module project; with code name base org.myorg.simplewizard (Ctrl-Shift-N and then find it in the New Project wizard).

  2. Right-click the project, choose New, choose Wizard. Make this selection:

    If you're using NetBeans IDE 5.0 Beta, the panel above will look different. (It's undergone quite a bit of change—not easy to make this panel clear, a lot of consequences flow out of decisions made here.)

  3. Fill in 'MyDestination' in the next panel and complete the wizard. You'll end up with something like this in the Projects window (the four highlighted files are the only ones you'll be working with):

  4. Now the fun begins. Broadly, there are five tasks that need to be done:
    • In the 'Design' part of the Visual component, design the wizard.
    • In the 'Source' part of the Visual component, set values based on user choices.
    • In the Wizard component, retrieve the current values from the Visual panel.
    • In the action class, do something with the values set in the Visual Panel.
    • In the layer.xml file, register the action class.

Here are some notes on each of the five tasks listed above:

  • Design the panel. Use Matisse (yay! you can use Matisse when designing the layout of modules) to add a button group, add three buttons, change labels ('Hawaii', 'Tahiti, 'Bahamas', for example), change names ('hawaii', 'tahiti', 'bahamas', for example), set first one as selected, add a label ('Preferred job location:', for example). Add the buttons to the button group. This is how it looks for me:

  • Set values. In the Visual component, add these to the top of the code:
    static final int BAHAMAS = 0;
    static final int HAWAII = 1;
    static final int TAHITI = 2;
    static final String DESTINATION_LOCATION = "destlocation";

    Add these lower down in the code:

    int getDestLocation() {
    return hawaii.isSelected() ? HAWAII : (bahamas.isSelected() ? BAHAMAS : TAHITI);
    }
    static String getAsString(int type) {
    return type == HAWAII ? "Hawaii" : (type == BAHAMAS ? "Bahamas" : "Tahiti");
    }

    Change the getName() method so that it returns "Job Location" (this will be displayed in the left sidebar of the wizard).

  • Pass the values. In the Wizard component, retrieve the values like this:
    private int getDestinationLocationFromVisualPanel() {
    return ((MyDestinationVisualPanel1) component).getDestLocation();
    }

    Then change the default storeSettings method to this:

    public void storeSettings(Object settings) {
    ((WizardDescriptor) settings).putProperty(MyDestinationVisualPanel1.DESTINATION_LOCATION, Integer.valueOf(getDestinationLocationFromVisualPanel()));
    }

  • Do something with the values. In the action class, add this to the end of the performAction method:
    if (!cancelled) {
    StringBuffer message = new StringBuffer();
    Integer destLocation = (Integer)
    wizardDescriptor.getProperty(MyDestinationVisualPanel1.DESTINATION_LOCATION);
    message.append("You're going to: " +
    MyDestinationVisualPanel1.getAsString(destLocation.intValue()));
    DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(message.toString()));
    }

    Change the getName() method so that it returns "Job Seeker Wizard" (this will be displayed as the action's label in the menu bar). Do the same for the wizardDescriptor.setTitle in the peformAction() method; this sets the title of the wizard.

  • Register the action class. Specify where/how the action class is to be invoked, by adding something like the following to the module's layer.xml:

    <folder name="Actions">
    <folder name="Build">
    <file name="org-myorg-simplewizard-SampleAction.instance">
    <attr name="instanceClass" stringvalue="org.myorg.simplewizard.SampleAction"/>
    </file>
    </folder>
    </folder>
    <folder name="Menu">
    <folder name="Window">
    <file name="org-myorg-simplewizard.SampleAction.shadow">
    <attr name="originalFile" stringvalue="Actions/Build/org-myorg-simplewizard-SampleAction.instance"/>
    </file>
    </folder>
    </folder>

Now install the module. Look for the action in the place where you registered it in the layer.xml (above, the action is registered as a menu item in the Window menu):

When you choose the menu item, you get the wizard:

When you click Finish, this dialog is displayed, showing your selection in the wizard:

Yay, you're done. Your first wizard.

Update: There are more parts to this series... Part 1, Part 2, Part 4, and Part 5.

Join the discussion

Comments ( 10 )
  • neeti Monday, October 15, 2007

    Would there be any means of using the Enter key to facilitate Finish instead of the usual click on Finish Button for a collection of wizard descriptors?

    Thanks


  • Geertjan Monday, October 15, 2007

    I think that's how it should work already neeti. If it doesn't, I think it would be a bug. You can write to dev@openide.netbeans.org with this question and see what the experts/users of the NetBeans Platform say.


  • ashwin Tuesday, December 29, 2009

    I know posting a comment this late would not find a response but let me put across my question anyway-

    I am planning to design a "configurator wizard" that will have several panels (some of which are conditionally displayed based on the choices made in previous panels), and I am unable to find solutions for two things:

    1. How to display a different panel based on a radio selection made in one panel?

    2. After the user completes the wizard I want to provide a way for him to save the entire configuration done (I know this is easy to write to a file as all the data is available), and be able to load it when he/she starts the wizard next time. Here I want all the panels to show configuration from the saved file, the user may click finish as it is or edit as needed by going back and forth.

    Do let me know any hints please.


  • Joseph Monday, August 9, 2010

    I'm very confused on how the action wizard works.

    When is the performAction() invoked ?

    The performAction() seems to be creating the panels and starting off the wizard by setting the dialog to visible. My question is...When is the perfomAction() invoked ? Is it invoked once to start off the wizard or is it invoked whenever the next or finished button is clicked.


  • Geertjan Wielenga Monday, August 9, 2010

    Instead of reading a blog, it's much better to read a tutorial.

    http://platform.netbeans.org/tutorials/nbm-wizard.html


  • Joseph Monday, August 9, 2010

    I've read through the tutorial and others relating to it. None of these explain the role of the performAction() method. It look strange to me that the same method is called to start the wizard by creating and init the panels and it is also called when the finish button is clicked on the last panel.


  • Geertjan Monday, August 9, 2010

    If you had followed the tutorial, you wouldn't be using a performAction method at all... Please use the dev mailing list for further questions -- simply because I'm not available all the time and there are many more developers answering questions there (hundreds) than there are here (one).


  • Zoran Sevarac Sunday, November 14, 2010

    Wizards remmembers previously entered values either user clicks cancel or finnish. How to clear previously entered values in wizard? Thanks.


  • guest Thursday, April 25, 2013

    i've used static wizard for my project following dis link http://platform.netbeans.org/tutorials/nbm-wizard.html . Now i want to create a JAR file of it, so tat i can run it on linux. I know how to create JAR file for simple java applications, but for netbeans wizard module im unable to do. Please help me!!!!!!!!!


  • Geertjan Thursday, April 25, 2013

    Just write to the mailing list (dev@platform.netbeans.org), assuming you're a member of it, and ask your questions there. Thanks.


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.