Package org.geomajas.widget.utility.smartgwt.client.wizard

Source Code of org.geomajas.widget.utility.smartgwt.client.wizard.Wizard$NextHandler

/*
* This is part of Geomajas, a GIS framework, http://www.geomajas.org/.
*
* Copyright 2008-2011 Geosparc nv, http://www.geosparc.com/, Belgium.
*
* The program is available in open source according to the GNU Affero
* General Public License. All contributions in this program are covered
* by the Geomajas Contributors License Agreement. For full licensing
* details, see LICENSE.txt in the project root.
*/

package org.geomajas.widget.utility.smartgwt.client.wizard;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import org.geomajas.annotation.FutureApi;

import com.google.gwt.user.client.ui.Widget;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;

/**
* <p>
* Wizard class that lets a user step through a set of pages to accomplish a certain task. In addition to the classical
* NEXT, BACK, CANCEL and FINISH buttons, this wizard provides direct page navigation by means of a button per page
* (typically shown in a vertical navigation bar). This abstract class handles all the navigation logic and state
* handling of the buttons. The NEXT and BACK button are handled directly by this class. The CANCEL and FINISH button
* should be handled by concrete subclasses by implementing the abstract {@link onCancel()} and {@link onFinish()}
* methods.
* </p>
*
* <p>
* The view is abstracted through the {@link WizardView} interface. A default implementation, called
* {@link WizardWidget} is provided.
* </p>
*
* <p>
* Individual pages can be created by sub-classing the {@link WizardPage} class. This class has a template parameter
* DATA, which represents the type of the data context that is passed to all pages on startup.
* </p>
*
* <p>
* Typical usage is as follows:
* </p>
* <code>
* <pre>
*   Wizard<MyData> wizard = new MyWizard(new WizardWidget<MyData>());
*   wizard.addPage(new MyPage1());
*   wizard.addPage(new MyPage2());
*   wizard.addPage(new MyPage3());
*   // add the view to your application
*   layout.addMember(wizard.getView());
*   // pass the data context and show the first page
*   wizard.start(new MyData());
*
*   </pre>
* </code>
*
* @param <DATA> data type
*
* @author Jan De Moerloose
*/
@FutureApi
public abstract class Wizard<DATA> {

  private List<WizardPage<DATA>> pages;

  private WizardPage<DATA> currentPage;

  private WizardView<DATA> wizardView;

  private boolean started;

  /**
   * Create a wizard with the specified view.
   *
   * @param wizardView
   *            the view part
   */
  public Wizard(WizardView<DATA> wizardView) {
    this.wizardView = wizardView;
    pages = new ArrayList<WizardPage<DATA>>();
  }

  /**
   * Returns the view part of this wizard.
   *
   * @return the view part.
   */
  public WizardView<DATA> getView() {
    return wizardView;
  }

  /**
   * Starts or restarts this wizard by clearing all pages and presenting the first page to the user. This method
   * should only be called after all pages have been added. After this method has been called, no more pages can be
   * added.
   *
   * @param wizardData
   */
  public void start(DATA wizardData) {
    if (!started) {
      initHandlers();
    }
    for (WizardPage<DATA> page : pages) {
      page.clear();
      page.setWizardData(wizardData);
    }
    ListIterator<WizardPage<DATA>> iterator = pages.listIterator();
    if (iterator.hasNext()) {
      setCurrentPage(iterator.next());
    }
  }

  /**
   * Returns the currently visible page.
   *
   * @return the current page
   */
  public WizardPage<DATA> getCurrentPage() {
    return currentPage;
  }

  /**
   * Sets the current page of this wizard. As this method forces the current page, it should only be used after
   * checking validity of the previous pages.
   *
   * @param newPage
   *            the page to be set
   */
  protected void setCurrentPage(WizardPage<DATA> newPage) {
    currentPage = newPage;
    updateState();
    wizardView.setCurrentPage(currentPage);
    currentPage.show();
  }

  /**
   * Adds a page to this wizard. The page order is determined by the order in which pages are added.
   *
   * @param page
   *            the page to be added
   */
  public void addPage(WizardPage<DATA> page) {
    if (!started) {
      WizardPage<DATA> lastPage = pages.size() > 0 ? pages.get(pages.size() - 1) : null;
      if (lastPage != null) {
        lastPage.setNextPage(page);
        page.setBackPage(lastPage);
      }
      pages.add(page);
      wizardView.addPageToView(page);
    }
  }

  /**
   * Called when the user presses the CANCEL button.
   */
  protected abstract void onCancel();

  /**
   * Called when the user presses the FINISH button.
   */
  protected abstract void onFinish();

  private void initHandlers() {
    for (WizardButton<DATA> button : wizardView.getButtons()) {
      switch (button.getType()) {
        case PREVIOUS:
          button.addClickHandler(new BackHandler());
          break;
        case CANCEL:
          button.addClickHandler(new CancelHandler());
          break;
        case FINISH:
          button.addClickHandler(new FinishHandler());
          break;
        case NEXT:
          button.addClickHandler(new NextHandler());
          break;
        case PAGE:
          button.addClickHandler(new GoToHandler(button.getPage()));
          break;

      }
    }
    started = true;
  }

  private void updateState() {
    for (WizardButton<DATA> button : wizardView.getButtons()) {
      switch (button.getType()) {
        case PREVIOUS:
          if (currentPage.getBackPage() != null) {
            button.setEnabled(true);
          } else {
            button.setEnabled(false);
          }
          break;
        case CANCEL:
          button.setEnabled(true);
          break;
        case FINISH:
          if (currentPage.getNextPage() == null) {
            button.setEnabled(true);
          } else {
            button.setEnabled(false);
          }
          break;
        case NEXT:
          if (currentPage.getNextPage() != null) {
            button.setEnabled(true);
          } else {
            button.setEnabled(false);
          }
          break;
        case PAGE:
          button.setActive(button.getPage() == currentPage);
          button.setEnabled(button.getPage().canShow());
          Widget widget = button.getPage().asWidget();
          if (widget != null) {
            widget.setVisible(button.getPage() == currentPage);
          }
          break;
      }
    }
  }

  /**
   * Performs FINISH operation.
   *
   * @author Jan De Moerloose
   *
   */
  class FinishHandler implements ClickHandler {

    public void onClick(ClickEvent event) {
      onFinish();
    }

  }

  /**
   * Performs CANCEL operation.
   *
   * @author Jan De Moerloose
   *
   */
  class CancelHandler implements ClickHandler {

    public void onClick(ClickEvent event) {
      onCancel();
    }

  }

  /**
   * Performs BACK operation.
   *
   * @author Jan De Moerloose
   *
   */
  class BackHandler implements ClickHandler {

    public void onClick(ClickEvent event) {
      setCurrentPage(currentPage.getBackPage());
    }

  }

  /**
   * Performs NEXT operation.
   *
   * @author Jan De Moerloose
   *
   */
  class NextHandler implements ClickHandler {

    public void onClick(ClickEvent event) {
      if (currentPage.validate()) {
        setCurrentPage(currentPage.getNextPage());
      }
    }

  }

  /**
   * Performs page operation.
   *
   * @author Jan De Moerloose
   *
   */
  class GoToHandler implements ClickHandler {

    private WizardPage<DATA> page;

    public GoToHandler(WizardPage<DATA> page) {
      this.page = page;
    }

    public void onClick(ClickEvent event) {
      // must check all previous pages and stop if we reach an invalid page
      // because user may have changed page info behind our back !
      Iterator<WizardPage<DATA>> it = pages.iterator();
      while (it.hasNext()) {
        WizardPage<DATA> p = it.next();
        if (p == page || !p.validate()) {
          setCurrentPage(p);
          break;
        }
      }
    }

  }

}
TOP

Related Classes of org.geomajas.widget.utility.smartgwt.client.wizard.Wizard$NextHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.