WizardDemo.java
package examples;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import sos.wizard.*;
public class WizardDemo implements java.io.Serializable
{
public static void main(String[] args)
{
try
{
WizardDemo demo = new WizardDemo();
demo.run();
}
catch( Throwable e )
{
e.printStackTrace();
}
finally
{
System.exit( 0 ); }
}
private static JCheckBox createCheckBox( String text, Font font,
boolean isSelected, final JLabel confirmationLabel,
final String selectedText, final String unselectedText )
{
final JCheckBox checkBox = new JCheckBox( text, isSelected );
checkBox.setFont( font );
checkBox.setOpaque( false );
checkBox.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent event )
{
if( checkBox.isSelected() )
confirmationLabel.setText( selectedText );
else
confirmationLabel.setText( unselectedText );
}
} );
return checkBox;
}
private static JLabel createLabel( String text, Font font )
{
JLabel label = new JLabel( text );
if( font != null )
label.setFont( font );
return label;
}
private static JPanel createPanel( LayoutManager layout )
{
JPanel panel = new JPanel();
panel.setOpaque( false );
panel.setLayout( layout );
return panel;
}
private static JRadioButton createRadioButton( String text,
Font font, boolean isSelected,
final JLabel confirmationLabel, final String selectedText )
{
final JRadioButton radioButton = new JRadioButton( text, isSelected );
radioButton.setFont( font );
radioButton.setOpaque( false );
radioButton.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent event )
{
if( radioButton.isSelected() )
confirmationLabel.setText( selectedText );
}
} );
return radioButton;
}
private static Task createSampleTask()
{
return new AbstractTask( "Finishing wizard..." ) {
public void run()
{
for( int i = 1; i <= 100; i++ )
{
if( shouldAbort() )
break;
try
{
Thread.currentThread().sleep( 30 );
}
catch( InterruptedException ie )
{
Thread.currentThread().interrupt();
}
setProgress( i );
}
}
public boolean isInterruptible()
{
return true;
}
};
}
public void run()
{
Font font = new JTextField().getFont();
Page[] pages = new Page[5];
Object overviewMessage = "<html>This wizard will step you through " +
"the creation of your own sample wizard. It demonstrates the " +
"capabilities and flexibility of Side of Software's Wizard " +
"Library. By default, the look and feel of these wizards " +
"follow the guidelines set forth in Volume II of <i>Java<sup>" +
"<font size=-2>TM</font></sup> Look and Feel Design Guidelines" +
"</i>.<p><p>The programmer must supply the wizard's content. Any " +
"component may be placed in a wizard page. This page consists of " +
"a single <code>JTextPane</code>, displaying HTML text.</html>";
pages[0] = new OptionPage( "Overview", overviewMessage );
JPanel choicesPanel = createPanel( new GridBagLayout() );
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.FIRST_LINE_START;
c.insets = new Insets( 1, 6, 1, 6 );
c.gridx = 0; c.gridy = 0;
choicesPanel.add( createLabel( "Title:", null ), c );
final JLabel confirmationTitleField = createLabel( "My First Wizard", font );
c.gridx = 1; c.gridy = 0;
choicesPanel.add( confirmationTitleField, c );
c.gridx = 0; c.gridy = 1;
choicesPanel.add( createLabel( "Side Panel:", null ), c );
final JLabel confirmationSidePanelField = createLabel( "List of Steps", font );
c.gridx = 1; c.gridy = 1;
choicesPanel.add( confirmationSidePanelField, c );
c.gridx = 0; c.gridy = 2;
choicesPanel.add( createLabel( "Help Button:", null ), c );
final JLabel confirmationHelpButtonField = createLabel( "No", font );
c.gridx = 1; c.gridy = 2;
choicesPanel.add( confirmationHelpButtonField, c );
c.gridx = 0; c.gridy = 3;
choicesPanel.add( createLabel( "Last Button:", null ), c );
final JLabel confirmationLastButtonField = createLabel( "No", font );
c.gridx = 1; c.gridy = 3;
choicesPanel.add( confirmationLastButtonField, c );
c.gridx = 0; c.gridy = 4;
choicesPanel.add( createLabel( "Progress Page:", null ), c );
final JLabel confirmationProgressPageField = createLabel( "Yes", font );
c.gridx = 1; c.gridy = 4;
choicesPanel.add( confirmationProgressPageField, c );
c.gridx = 0; c.gridy = 5;
choicesPanel.add( createLabel( "Summary Page:", null ), c );
final JLabel confirmationSummaryPageField = createLabel( "Yes", font );
c.gridx = 1; c.gridy = 5;
choicesPanel.add( confirmationSummaryPageField, c );
JPanel panel = createPanel( new BorderLayout() );
panel.setBorder( BorderFactory.createEmptyBorder( 6, 24, 0, 0 ));
panel.add( choicesPanel, BorderLayout.BEFORE_LINE_BEGINS );
Object confirmationMessage = new Object[] {
"<html>Your current choices are listed below. To create " +
"your sample wizard, press <b>Finish</b>. To modify any of " +
"your choices, press <b>Back</b>.<p><p></html>",
panel
};
pages[4] = new OptionPage( "Confirmation", confirmationMessage );
final JTextField titleTextField = new JTextField( "My First Wizard" ) {
protected void processFocusEvent( FocusEvent event )
{
super.processFocusEvent( event );
selectAll();
}
};
Object[] titleMessage = new Object[] {
"<html>Provide a title for your wizard.<p><html>",
titleTextField,
"<html><p><p>Each page can specify when it is incomplete " +
"or invalid. This page is not complete if the above text field " +
"is empty. Note that the <b>Next</b> and <b>Last</b> buttons " +
"become disabled if the page is incomplete. This page is invalid " +
"if the supplied text contains a non-alphanumeric character. Try " +
"typing \"Wizard?\" and clicking <b>Next</b>.</html>"
};
final OptionPage titlePage = new OptionPage( "Wizard Title", titleMessage ) {
public void validate() throws InvalidPageException
{
String title = titleTextField.getText();
for( int i = 0; i < title.length(); i++ )
{
char ch = title.charAt( i );
if( !Character.isLetterOrDigit( ch ) && !Character.isWhitespace( ch ))
{
titleTextField.requestFocus();
throw new InvalidPageException( "The title may only contain letters and digits." );
}
}
}
};
titleTextField.getDocument().addDocumentListener( new DocumentListener() {
public void insertUpdate( DocumentEvent e )
{
update();
}
public void changedUpdate( DocumentEvent e )
{
update();
}
public void removeUpdate( DocumentEvent e )
{
update();
}
private void update()
{
String title = titleTextField.getText();
confirmationTitleField.setText( title );
if( title.length() == 0 )
titlePage.setComplete( false );
else
titlePage.setComplete( true );
}
} );
pages[1] = titlePage;
ButtonGroup sidePanelButtonGroup = new ButtonGroup();
JRadioButton listOfStepsRadioButton = createRadioButton( "List of Steps",
font, true, confirmationSidePanelField, "List of Steps" );
JRadioButton graphicRadioButton = createRadioButton( "Picture",
font, false, confirmationSidePanelField, "Picture" );
JRadioButton noneRadioButton = createRadioButton( "Nothing",
font, false, confirmationSidePanelField, "Nothing" );
sidePanelButtonGroup.add( listOfStepsRadioButton );
sidePanelButtonGroup.add( graphicRadioButton );
sidePanelButtonGroup.add( noneRadioButton );
JPanel sidePanelButtons = createPanel( null );
sidePanelButtons.setLayout( new BoxLayout( sidePanelButtons, BoxLayout.PAGE_AXIS ));
sidePanelButtons.add( listOfStepsRadioButton );
sidePanelButtons.add( graphicRadioButton );
sidePanelButtons.add( noneRadioButton );
sidePanelButtons.setBorder( BorderFactory.createEmptyBorder( 0, 12, 0, 0 ));
JPanel buttonPanel = createPanel( new BorderLayout() );
buttonPanel.add( sidePanelButtons, BorderLayout.BEFORE_LINE_BEGINS );
Object sidePanelMessage = new Object[] {
"<html>The library allows you to place any component in a " +
"wizard's left side. The recommended practice is to display a " +
"list of the steps, as is used here. At times, it is desirable " +
"to show a picture or nothing at all.<p><p>What type of side " +
"panel do you want your sample wizard to have?<p></html>",
buttonPanel
};
pages[2] = new OptionPage( "Wizard Side Panel", sidePanelMessage );
JCheckBox helpButtonCheckBox = createCheckBox( "Show a Help button",
font, false, confirmationHelpButtonField, "Yes", "No" );
JCheckBox lastButtonCheckBox = createCheckBox( "Show a Last button",
font, false, confirmationLastButtonField, "Yes", "No" );
JCheckBox progressPageCheckBox = createCheckBox( "Show a progress page " +
"while task is finishing",
font, true, confirmationProgressPageField, "Yes", "No" );
JCheckBox summaryPageCheckBox = createCheckBox( "Show a summary page " +
"after task finished",
font, true, confirmationSummaryPageField, "Yes", "No" );
JPanel optionCheckBoxes = createPanel( null );
optionCheckBoxes.setLayout( new BoxLayout( optionCheckBoxes, BoxLayout.PAGE_AXIS ));
optionCheckBoxes.add( helpButtonCheckBox );
optionCheckBoxes.add( lastButtonCheckBox );
optionCheckBoxes.add( progressPageCheckBox );
optionCheckBoxes.add( summaryPageCheckBox );
optionCheckBoxes.setBorder( BorderFactory.createEmptyBorder( 0, 12, 0, 0 ));
JPanel checkBoxPanel = createPanel( new BorderLayout() );
checkBoxPanel.add( optionCheckBoxes, BorderLayout.BEFORE_LINE_BEGINS );
Object optionsMessage = new Object[] {
"<html>The library provides many opportunities to customize a wizard, " +
"such as changing its font, color, or preferred size. A few additional " +
"options are listed below.<p><p>Check the options you would like your " +
"wizard to have.<p><html>",
checkBoxPanel
};
pages[3] = new OptionPage( "Wizard Options", optionsMessage );
Object summaryMessage = new Object[] {
"<html>You have successfully created your sample wizard. It " +
"will launch after you press <b>Close</b>.</html>"
};
Page summaryPage = new OptionPage( "Summary", summaryMessage );
DefaultWizardModel wizardModel = new DefaultWizardModel( pages, null, summaryPage );
wizardModel.setSupportsLast( true );
wizardModel.setProgressPageIsUsed( false );
JWizard wizard = new JWizard( wizardModel );
wizard.setFont( font );
wizard.setDefaultAccessory( JWizard.DEFAULT_ACCESSORY_STEPS );
int result = wizard.showDialog( null, "Side of Software Wizard Library Demo" );
if( result != WizardModel.WIZARD_FINISHED )
return;
final DefaultWizardModel sampleWizardModel = new DefaultWizardModel();
final JRadioButton option1RadioButton = new JRadioButton( "Show pages 2-4", true );
option1RadioButton.setFont( font );
option1RadioButton.setOpaque( false );
JRadioButton option2RadioButton = new JRadioButton( "Show pages 2a, 4" );
option2RadioButton.setFont( font );
option2RadioButton.setOpaque( false );
ButtonGroup sampleButtonGroup = new ButtonGroup();
sampleButtonGroup.add( option1RadioButton );
sampleButtonGroup.add( option2RadioButton );
JPanel optionsPanel = createPanel( null );
optionsPanel.setLayout( new BoxLayout( optionsPanel, BoxLayout.Y_AXIS ));
optionsPanel.add( option1RadioButton );
optionsPanel.add( option2RadioButton );
JPanel sampleButtonPanel = createPanel( new BorderLayout() );
sampleButtonPanel.add( optionsPanel, BorderLayout.BEFORE_LINE_BEGINS );
Object selectionMessage = new Object[] {
"<html>A wizard's pages can change dynamically. In this wizard, " +
"the subsequent pages depend on your selection here.</html>",
sampleButtonPanel
};
Page selectionPage = new OptionPage( "Selection Page", selectionMessage );
boolean showProgressPage = progressPageCheckBox.isSelected();
boolean showSummaryPage = summaryPageCheckBox.isSelected();
Object page4Message;
if( showProgressPage && showSummaryPage )
page4Message = "<html>After pressing <b>Finish</b>, a progress " +
"page will show the progress of a fake task. If the task " +
"successfully finishes, you will be shown a final summary page, " +
"allowing you to close the dialog.</html>";
else if( showProgressPage && !showSummaryPage )
page4Message = "<html>After pressing <b>Finish</b>, a progress " +
"page will show the progress of a fake task. If the task " +
"successfully finishes, you will be allowed to close the " +
"dialog.</html>";
else if( !showProgressPage && showSummaryPage )
page4Message = "<html>After pressing <b>Finish</b>, a fake task " +
"will execute. Lengthy tasks typically show a progress page " +
"that informs the user of the task's progress. After the task " +
"finishes, you will be shown a final summary page, allowing you " +
"to close the dialog.</html>";
else
page4Message = "<html>Thank you for running the Wizard Demo. If you " +
"have any questions or comments please email Side of Software.<p><p>" +
"The source code for this demonstration is available on the " +
"library's website.</html>";
final Page page4 = new OptionPage( "Page 4", page4Message );
DefaultWizardModel.Transition selectionPageTransition = new DefaultWizardModel.TransitionAdapter() {
public void stepNext()
{
if( option1RadioButton.isSelected() )
{
Object page2Message = "<html>This library separates the model " +
"from the view to achieve greater flexibility. The wizard model " +
"is viewed through a <code>JWizard</code> component, while a " +
"page is viewed through a page editor.</html>";
Page page2 = new OptionPage( "Page 2", page2Message );
Object page3Message = "<html>The <code>JWizard</code> class is a " +
"user-interface component that follows the Swing conventions. " +
"For example, it<ul><li>Delegates its rendering to a look-and-" +
"feel delegate</li><li>Implements accessibility</li><li>Sends " +
"property change events when its state changes</li><li>Sends " +
"action events when an action occurs</li></ul></html>";
Page page3 = new OptionPage( "Page 3", page3Message );
sampleWizardModel.push( page2 );
sampleWizardModel.addLast( page3 );
sampleWizardModel.addLast( page4 );
}
else
{
Object page2aMessage = "<html>It is possible to hide the control " +
"buttons and operate the wizard programmatically. As a result, " +
"you can implement an automatic slide show.</html>";
Page page2a = new OptionPage( "Page 2a", page2aMessage );
sampleWizardModel.push( page2a );
sampleWizardModel.addLast( page4 );
}
}
public void stepBack()
{
int numDynamicPages = option1RadioButton.isSelected()? 3 : 2;
for( int i = 0; i < numDynamicPages; i++ )
sampleWizardModel.removeLast();
}
};
sampleWizardModel.addLast( selectionPage, selectionPageTransition );
sampleWizardModel.setLastPage( page4 );
Task sampleFinishTask = createSampleTask();
Page sampleSummaryPage = null;
if( showSummaryPage )
{
Object sampleSummaryMessage = "<html>Thank you for running the Wizard " +
"Demo. If you have any questions or comments please email Side " +
"of Software.<p><p>The source code for this demonstration is " +
"available on the library's website.</html>";
sampleSummaryPage = new OptionPage( "Summary", sampleSummaryMessage );
}
sampleWizardModel.setFinishTask( sampleFinishTask );
sampleWizardModel.setSummaryPage( sampleSummaryPage );
final JWizard sampleWizard = new JWizard( sampleWizardModel );
PageEditor customProgressPageEditor = new ProgressPageEditor() {
public boolean confirmStop()
{
String message = "Are you sure you want to stop the execution?";
int response = JOptionPane.showConfirmDialog( sampleWizard, message,
"Confirm Stop", JOptionPane.YES_NO_OPTION );
if( response == JOptionPane.YES_OPTION )
return true;
return false;
}
};
sampleWizard.setDefaultPageEditor( ProgressPage.class, customProgressPageEditor );
boolean showHelpButton = helpButtonCheckBox.isSelected();
sampleWizard.setHelpButtonIsShown( showHelpButton );
sampleWizard.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent event )
{
String command = event.getActionCommand();
if( JWizard.HELP_ACTION.equals( command ))
JOptionPane.showMessageDialog( sampleWizard,
"The programmer is responsible for responding to the " +
"Help button." );
}
} );
boolean showLastButton = lastButtonCheckBox.isSelected();
sampleWizardModel.setSupportsLast( showLastButton );
sampleWizardModel.setProgressPageIsUsed( showProgressPage );
if( listOfStepsRadioButton.isSelected() )
{
sampleWizard.setDefaultAccessory( JWizard.DEFAULT_ACCESSORY_STEPS );
}
else if( graphicRadioButton.isSelected() )
{
Icon icon = new ImageIcon( WizardDemo.class.getClassLoader().getResource(
"examples/WizardGraphic.jpg" ));
JLabel sampleGraphics = new JLabel( icon );
sampleWizard.setAccessory( sampleGraphics );
}
String sampleTitle = titleTextField.getText();
sampleWizard.showDialog( null, sampleTitle );
}
}