DynamicModel.java :  » Swing-Library » wizard-framework » org » pietschy » wizard » models » Java Open Source

Java Open Source » Swing Library » wizard framework 
wizard framework » org » pietschy » wizard » models » DynamicModel.java
/**
 * Wizard Framework
 * Copyright 2004 - 2005 Andrew Pietsch
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * $Id: DynamicModel.java,v 1.6 2005/08/13 01:19:03 pietschy Exp $
 */

package org.pietschy.wizard.models;

import org.pietschy.wizard.AbstractWizardModel;
import org.pietschy.wizard.WizardStep;
import org.pietschy.wizard.WizardModel;

import java.util.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;

/**
 * The DynamicModel is very similar to the static model, except that steps can be dynamically removed
 * from the wizard flow.
 * <pre>
 * // create a subclass of DynamicModel
 * MyDynamicModel model = new MyDynamicModel();
 *
 * // add the first step..
 * model.add(new MyFirstStep());
 *
 * // add an optional step..
 * model.add(new MyOptionalStep(), new Condition()
 * {
 *    public boolean evaluate(WizardModel model)
 *    {
 *        return ((MyDynamicModel) model).isOptionalRequired();
 *    }
 * });
 *
 * // add the last step.
 * model.add(new MyLastStep());
 *
 * // now create the wizard and use it..
 * Wizard wizard = new Wizard(model);
 * </pre>
 * It is also worth noting that steps that implement {@link Condition} can be added using the basic
 * {@link #add(WizardStep)} and the model will automatically add them as an optional step.
 * <p>
 *
 *
 *
 * @see #add(WizardStep)
 * @see #add(WizardStep, Condition)
 */
public class
DynamicModel
extends AbstractWizardModel
{

   /** An implementation of {@link Condition} that always returns <tt>true</tt>. */
   public static final Condition TRUE_CONDITION = new Condition()
   {
      public boolean evaluate(WizardModel model)
      {
         return true;
      }
   };

   private ArrayList steps = new ArrayList();
   private ArrayList conditions = new ArrayList();

   private Stack history = new Stack();

   /**
    * Creates a new DynamicModel.
    */
   public
   DynamicModel()
   {
   }

   /**
    * Adds the next step to the wizard.  If the {@link WizardStep} implements {@link Condition}, then this method is
    * equivalent to calling {@link #add(WizardStep, Condition) add(step, (Condition)step)}, other wise it is equivalent to
    * calling {@link #add(org.pietschy.wizard.WizardStep, Condition) add(step, TRUE_CONDITION)}.
    * <p>
    * This allows the easy use of {@link WizardStep}s that determine the condition under which they are displayed.
    *
    * @param step the step to added.
    */
   public void
   add(WizardStep step)
   {
      if (step instanceof Condition)
         add(step, (Condition) step);
      else
         add(step, TRUE_CONDITION);
   }

   /**
    * Adds an optional step to the model.  The step will only be displayed if the specified
    * condition is met.
    *
    * @param step      the {@link org.pietschy.wizard.WizardStep} to add.
    * @param condition the {@link Condition} under which it should be included in the wizard.
    */
   public void
   add(WizardStep step, Condition condition)
   {
      addCompleteListener(step);
      steps.add(step);
      conditions.add(condition);
   }

   public void
   nextStep()
   {
      WizardStep currentStep = getActiveStep();
      history.push(currentStep);
      setActiveStep(findNextVisibleStep(currentStep));
   }

   public void
   previousStep()
   {
      WizardStep step = (WizardStep) history.pop();
      setActiveStep(step);
   }

   public void
   lastStep()
   {
      WizardStep activeStep = getActiveStep();
      history.push(activeStep);
      setActiveStep(findLastStep());
   }

   public void
   reset()
   {
      history.clear();
      setActiveStep(findNextVisibleStep(null));
   }

   public boolean
   isLastStep(WizardStep step)
   {
      return findLastStep().equals(step);
   }

   /**
    * Forces the model to re-evaluate it's current state.  This method will re-evalute the
    * conditional steps by calling {@link Condition#evaluate(org.pietschy.wizard.WizardModel)}.
    * <p>
    * Subclasses that override this method must be sure to invoke <tt>super.refreshModelState()</tt>.
    */
   public void
   refreshModelState()
   {
      WizardStep activeStep = getActiveStep();
      setNextAvailable(activeStep != null && activeStep.isComplete() && !isLastStep(activeStep));
      setPreviousAvailable(activeStep != null && !history.isEmpty());
      setLastAvailable(activeStep != null && allStepsComplete() && !isLastStep(activeStep));
      setCancelAvailable(true);
   }

   /**
    * Returns true if all included steps in the wizard return <tt>true</tt> from {@link WizardStep#isComplete}.  This
    * is primarily used to determine if the last button can be enabled.
    * <p>
    * Please note that this method ignores all steps for which their {@link Condition} returns false.
    *
    * @return <tt>true</tt> if all the visible steps in the wizard are complete, <tt>false</tt> otherwise.
    */
   public boolean
   allStepsComplete()
   {
      for (int i = 0; i < steps.size(); i++)
      {
         WizardStep step = (WizardStep) steps.get(i);
         Condition condition = (Condition) conditions.get(i);

         if (condition.evaluate(this))
         {
            if (!step.isComplete())
               return false;
         }

      }

      return true;
   }


   public Iterator
   stepIterator()
   {
      return Collections.unmodifiableList(steps).iterator();
   }


   /**
    * @param currentStep
    * @return
    */
   private WizardStep
   findNextVisibleStep(WizardStep currentStep)
   {
      int startIndex = (currentStep == null) ? 0 : steps.indexOf(currentStep) + 1;

      for (int i = startIndex; i < conditions.size(); i++)
      {
         Condition condition = (Condition) conditions.get(i);
         if (condition.evaluate(this))
         {
            return (WizardStep) steps.get(i);
         }
      }

      throw new IllegalStateException("Wizard contains no more visible steps");
   }

   /**
    * @return
    */
   private WizardStep
   findLastStep()
   {
      for (int i = conditions.size() - 1; i >= 0; i--)
      {
         Condition condition = (Condition) conditions.get(i);
         if (condition.evaluate(this))
         {
            return (WizardStep) steps.get(i);
         }
      }

      throw new IllegalStateException("Wizard contains no visible steps");
   }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.