/*
* soapUI, copyright (C) 2004-2011 eviware.com
*
* soapUI is free software; you can redistribute it and/or modify it under the
* terms of version 2.1 of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details at gnu.org.
*/
package com.eviware.x.impl.swing;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.actions.UpdateableAction;
import com.eviware.soapui.support.DescriptionPanel;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.action.swing.DefaultActionList;
import com.eviware.soapui.support.components.JButtonBar;
import com.eviware.soapui.support.swing.ModalFrameUtil;
import com.eviware.soapui.support.types.StringToStringMap;
import com.eviware.x.form.WizardPage;
import com.eviware.x.form.XForm;
import com.eviware.x.form.XFormDialog;
import com.eviware.x.form.XFormField;
public class JWizardDialog extends SwingXFormDialog
{
private String name;
private ArrayList<String> pageNames = new ArrayList<String>();
private JFrame dialog;
private DescriptionPanel descriptionPanel;
private List<SwingXFormImpl> forms = new ArrayList<SwingXFormImpl>();
private JPanel pages;
private CardLayout cardLayout;
private HashMap<String, WizardPage> controllers = new HashMap<String, WizardPage>();
private int currentPage = 0;
private DefaultActionList actions;
private JButtonBar buttons;
public JWizardDialog( String name, XForm[] forms, Action helpAction, String description, ImageIcon icon )
{
this.name = name;
// Use JFrame instead of JDialog to get maximize button.
dialog = new JFrame( name );
initActions( helpAction );
cardLayout = new CardLayout();
pages = new JPanel( cardLayout );
for( XForm form : forms )
{
SwingXFormImpl swingFormImpl = ( SwingXFormImpl )form;
this.forms.add( swingFormImpl );
JPanel panel = swingFormImpl.getPanel();
panel.setBorder( BorderFactory.createEmptyBorder( 0, 0, 5, 0 ) );
addPage( form.getName(), panel );
}
buttons = UISupport.initFrameActions( actions, dialog );
if( description != null || icon != null )
{
descriptionPanel = UISupport.buildDescription( name, description, icon );
dialog.getContentPane().add( descriptionPanel, BorderLayout.NORTH );
}
dialog.getContentPane().add( pages, BorderLayout.CENTER );
buttons.setBorder( BorderFactory.createEmptyBorder( 3, 5, 3, 5 ) );
dialog.getContentPane().add( buttons, BorderLayout.SOUTH );
dialog.pack();
}
public XForm[] getForms()
{
List<XForm> result = new ArrayList<XForm>();
for( XForm form : forms )
result.add( form );
return result.toArray( new XForm[result.size()] );
}
public void dispose()
{
dialog.dispose();
}
private void initActions( Action helpAction )
{
actions = new DefaultActionList();
actions.addAction( new BackAction() );
actions.addAction( new NextAction() );
actions.addAction( new CancelAction() );
actions.addAction( new FinishAction() );
if( helpAction != null )
actions.addAction( helpAction );
}
public void addAction( Action action )
{
DefaultActionList actions = new DefaultActionList();
actions.addAction( action );
buttons.addActions( actions );
}
private void addPage( String name, JComponent component )
{
pages.add( component, name );
if( !pageNames.contains( name ) )
pageNames.add( name );
actions.update();
}
public void addPageController( WizardPage controller )
{
controllers.put( controller.getName(), controller );
}
public void addPageAndController( JComponent component, WizardPage controller )
{
addPage( controller.getName(), component );
addPageController( controller );
}
public void setValues( StringToStringMap values )
{
for( XForm form : forms )
form.setValues( values );
}
public void setOptions( String field, Object[] options )
{
for( XForm form : forms )
form.setOptions( field, options );
}
public XFormField getFormField( String name )
{
for( XForm form : forms )
{
XFormField formField = form.getFormField( name );
if( formField != null )
return formField;
}
return null;
}
public StringToStringMap getValues()
{
StringToStringMap result = new StringToStringMap();
for( XForm form : forms )
result.putAll( form.getValues() );
return result;
}
public void setVisible( boolean visible )
{
if( visible )
{
if( showPage( 0 ) )
{
Frame mainFrame = UISupport.getMainFrame();
UISupport.centerDialog( dialog, mainFrame );
// dialog.setVisible( visible );
ModalFrameUtil.showAsModal( dialog, mainFrame );
}
}
else
{
dialog.setVisible( visible );
}
}
public boolean validate()
{
return true;
}
public void setFormFieldProperty( String name, Object value )
{
for( XForm form : forms )
form.setFormFieldProperty( name, value );
}
public String getValue( String field )
{
for( XForm form : forms )
{
if( form.getComponent( field ) != null )
return form.getComponent( field ).getValue();
}
return null;
}
public void setValue( String field, String value )
{
for( XForm form : forms )
{
if( form.getComponent( field ) != null )
form.getComponent( field ).setValue( value );
}
}
public int getValueIndex( String name )
{
for( SwingXFormImpl form : forms )
{
if( form.getComponent( name ) != null )
{
Object[] options = form.getOptions( name );
if( options == null )
return -1;
return Arrays.asList( options ).indexOf( form.getComponentValue( name ) );
}
}
return -1;
}
public boolean show()
{
setReturnValue( XFormDialog.CANCEL_OPTION );
show( new StringToStringMap() );
return getReturnValue() == XFormDialog.OK_OPTION;
}
public void setWidth( int i )
{
dialog.setPreferredSize( new Dimension( i, ( int )dialog.getPreferredSize().getHeight() ) );
}
public void setSize( int w, int h )
{
dialog.setSize( w, h );
}
private boolean showPage( int pageNo )
{
currentPage = pageNo;
String pageName = pageNames.get( currentPage );
WizardPage page = controllers.get( pageName );
descriptionPanel.setTitle( page.getName() );
descriptionPanel.setDescription( page.getDescription() );
cardLayout.show( pages, pageName );
if( initPage( pageName, page ) )
{
actions.update();
return true;
}
else
{
setVisible( false );
return false;
}
}
private boolean initPage( String pageName, WizardPage page )
{
try
{
dialog.setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ) );
return page.init();
}
catch( Exception e )
{
dialog.setCursor( Cursor.getDefaultCursor() );
SoapUI.logError( e );
UISupport.showInfoMessage( pageName + " could not be initialized", this.name );
return false;
}
finally
{
dialog.setCursor( Cursor.getDefaultCursor() );
}
}
private boolean runCurrentPage()
{
String pageName = pageNames.get( currentPage );
WizardPage controller = controllers.get( pageName );
try
{
dialog.setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ) );
return controller.run();
}
catch( Exception e )
{
dialog.setCursor( Cursor.getDefaultCursor() );
SoapUI.logError( e );
UISupport.showInfoMessage( pageName + " failed", this.name );
return false;
}
finally
{
dialog.setCursor( Cursor.getDefaultCursor() );
}
}
private class BackAction extends AbstractAction implements UpdateableAction
{
public BackAction()
{
super( "< Back" );
}
public void update()
{
boolean enable = false;
if( currentPage > 0 )
{
String pageName = pageNames.get( currentPage - 1 );
WizardPage prevPage = controllers.get( pageName );
enable = prevPage.canGoBack();
}
setEnabled( enable );
}
public void actionPerformed( ActionEvent e )
{
showPage( currentPage - 1 );
}
}
private class NextAction extends AbstractAction implements UpdateableAction
{
public NextAction()
{
super( "Next >" );
}
public void update()
{
setEnabled( currentPage + 1 < pageNames.size() );
}
public void actionPerformed( ActionEvent evt )
{
if( runCurrentPage() )
showPage( currentPage + 1 );
else
setVisible( false );
}
}
private final class CancelAction extends AbstractAction implements UpdateableAction
{
public CancelAction()
{
super( "Cancel" );
}
public void update()
{
}
public void actionPerformed( ActionEvent e )
{
setReturnValue( XFormDialog.CANCEL_OPTION );
setVisible( false );
}
}
private final class FinishAction extends AbstractAction implements UpdateableAction
{
public FinishAction()
{
super( "Finish" );
}
public void update()
{
setEnabled( currentPage == pageNames.size() - 1 );
}
public void actionPerformed( ActionEvent e )
{
runCurrentPage();
setReturnValue( XFormDialog.OK_OPTION );
setVisible( false );
}
}
public void release()
{
dialog.dispose();
}
}