Saturday, June 18, 2011

Creating a Wizard in Java Swings

Getting started:
I was recently asked to create a windows style wizard (step by step execution) in Java.
Creating a wizard essentially means multiple panels should share the same display area. As a beginner, I had a thought that overlapping panels one over the other might work just fine. But you know what, it doesn't! With a lot of pain, you might even get it to work, but here's a thing: java has something called as CardLayout which is perfect for creating a wizard. Here's the tutorial on basic use of card layout. If you are highly impatient, lazy and have a short attention span like me or you think that you don't need to go into much detail of it, skip it.

A good design:
If you care for more than just getting the job done somehow, like I did after stupidly coding everything myself, which by the way was a bad design, now that I know of a better way, you should really think about sticking to some pattern. And by some pattern, I mean MVC which is an obvious (and as far as I know, the only) choice. Here's a very nice and straightforward article on what are your choices and considerations in terms of the architecture.

Ready to eat stuff:
I found out that OpenSwing framework, that I have used for pivot tables has good APIs for creating a wizard. It follows the pattern suggested on the Oracle/Java website mentioned previously and has a straightforward tutorial. Although, I think it would've been nice to have some more ready-made Intro panels (like licence panel) in the miscellaneous package, but you can always create your custom wizard inner panels and add it to the main wizard frame and you should be fine. If you read the Demo14 source, it's not that hard to make out what's happening in 10 minutes or so. Still, I'll brief some steps:

1. Create a client application -- This class will more likely contain the main method which eventually calls the WizardFrame class, and that's all it does.
2. WizardFrame -- This class creates the actual visible window. This class is a good place to add the inner panels on the wizard frame. By inner panels, I mean the screens that appear when you navigate
3. WizardController -- This class embeds the navigation logic of the wizard. Let's say you made a particular choice that requires 3rd screen to be displayed after the first (and not go to second screen at all), you can define that logic here.
4. Intro/First/Second Panels and so on... : These are the screens that are displayed when you navigate. These are extended from the WizardInnerPanel.
5. Execution Engine: Contains the execution logic. And mostly covers what happens when you click a cancel button or a finish button. In the demo application, finish and cancel button are referred to by the same method (getCurrentVisiblePanel.getCancelButton) which is kind of confusing at first, but 5 minutes of debugging will just do the trick.

Tip: Within 15 minutes of use, I found out that when you add WizardInnerPanel to the main wizard frame, the controls on the main wizard frame are reset. e.g. Say you have two radio buttons on the First Panel and initially none of them are selected and unless one of them is selected, you don't want user to go to next screen so you disable the Next button. However, if you've added all the necessary inner panels already, that next button might get re-enabled, if so, you might need to explicitly disable the next button in the init() function of the FirstPanel, like I did.

No comments:

Post a Comment