com.agnie.gwt.common.client.widget.WizardBar.java Source code

Java tutorial

Introduction

Here is the source code for com.agnie.gwt.common.client.widget.WizardBar.java

Source

/*******************************************************************************
 * Copyright (c) 2014 Agnie Technologies.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 * 
 * Contributors:
 *     Agnie Technologies - initial API and implementation
 ******************************************************************************/
package com.agnie.gwt.common.client.widget;

import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
import com.google.gwt.event.logical.shared.HasBeforeSelectionHandlers;
import com.google.gwt.event.logical.shared.HasSelectionHandlers;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * This wizard bar doesn't support click action on any of the steps in any state. If required the support need to be
 * added in this class it self.
 */
public class WizardBar extends Composite
        implements HasBeforeSelectionHandlers<Integer>, HasSelectionHandlers<Integer> {

    private static WizardBarResources resource = WizardBarResources.INSTANCE;

    static {
        resource.css().ensureInjected();
    }

    public interface Step {
    }

    private class ClickDelegatePanel extends Composite implements Step {

        private SimplePanel simplePanel;
        private boolean enabled = true;

        ClickDelegatePanel(Widget child) {

            simplePanel = new SimplePanel();
            simplePanel.setWidget(child);
            initWidget(simplePanel);
            simplePanel.addStyleName(resource.css().inactive());
        }

        @SuppressWarnings("unused")
        public SimplePanel getPanel() {
            return simplePanel;
        }

        public boolean isEnabled() {
            return enabled;
        }

        public void setEnabled(boolean enabled) {
            this.enabled = enabled;
        }

    }

    private HTMLPanel panel;
    private Widget selected;
    public static final String NO_MACRO = "#NO&";

    public WizardBar() {
        this(resource.css().wizard());
    }

    /**
     * Creates an empty Wizard bar.
     */
    public WizardBar(String styleClassName) {
        panel = new HTMLPanel("");
        initWidget(panel);
        panel.addStyleName(styleClassName);
    }

    public void setStyleClassName(String styleClassName) {
        panel.addStyleName(styleClassName);
    }

    public HandlerRegistration addBeforeSelectionHandler(BeforeSelectionHandler<Integer> handler) {
        return addHandler(handler, BeforeSelectionEvent.getType());
    }

    public HandlerRegistration addSelectionHandler(SelectionHandler<Integer> handler) {
        return addHandler(handler, SelectionEvent.getType());
    }

    public void addStep(String text) {
        addStep(null, text);
    }

    /**
     * Adds a new Step in wizard with specified text.
     * 
     * @param text
     *            the new Step's text
     */
    public void addStep(String label, String text) {
        StringBuffer html = new StringBuffer();
        if (label != null) {
            html.append("<em>" + processMacro(label) + "</em>");
        } else {
            html.append("<em>" + (getStepCount() + 1) + "</em>");
        }
        html.append("<span>" + text + "</span>");

        Anchor anchor = new Anchor();
        anchor.setHTML(html.toString());
        addStep(anchor);
    }

    private String processMacro(String text) {
        return text.replace(NO_MACRO, "" + (getStepCount() + 1));
    }

    /**
     * Adds a new Step in wizard with specified widget.
     * 
     * @param text
     *            the new Step's text
     */
    public void addStep(Widget step) {
        int currentCount = getStepCount();
        // Remove "final" style class from previous step widget

        ClickDelegatePanel delWidget = new ClickDelegatePanel(step);
        String className = "step" + currentCount;
        delWidget.addStyleName(className);
        delWidget.addStyleName(resource.css().lastElement());
        if (currentCount == 0) {
            delWidget.addStyleName(resource.css().firstElement());
        } else {
            ClickDelegatePanel p = (ClickDelegatePanel) panel.getWidget(currentCount - 1);
            p.removeStyleName(resource.css().lastElement());
        }

        panel.add(delWidget);
    }

    /**
     * Gets the index of Step that is currently selected.
     * 
     * @return the selected Step
     */
    public int getSelectedStep() {
        if (selected == null) {
            return -1;
        }
        return panel.getWidgetIndex(selected);
    }

    /**
     * Gets the given Step.
     * 
     * This method is final because the Step interface will expand. Therefore it is highly likely that subclasses which
     * implemented this method would end up breaking.
     * 
     * @param index
     *            the step's index
     * @return the step wrapper
     */
    public final Step getStep(int index) {
        if (index >= getStepCount()) {
            return null;
        }
        ClickDelegatePanel p = (ClickDelegatePanel) panel.getWidget(index);
        return p;
    }

    /**
     * Gets the number of Steps present.
     * 
     * @return the Step count
     */
    public int getStepCount() {
        return panel.getWidgetCount();
    }

    /**
     * Check if a Step is enabled or disabled. If disabled, the user cannot select the Step.
     * 
     * @param index
     *            the index of the Step
     * @return true if the Step is enabled, false if disabled
     */
    public boolean isStepEnabled(int index) {
        assert (index >= 0) && (index < getStepCount()) : "Step index out of bounds";
        ClickDelegatePanel delPanel = (ClickDelegatePanel) panel.getWidget(index);
        return delPanel.isEnabled();
    }

    /**
     * Removes the Step at the specified index.
     * 
     * @param index
     *            the index of the Step to be removed
     */
    public void removeStep(int index) {
        checkStepIndex(index);

        Widget toRemove = panel.getWidget(index);
        if (toRemove == selected) {
            selected = null;
        }
        panel.remove(toRemove);
    }

    /**
     * 
     * Go to next Step
     * 
     * @return <code>true</code> if successful, <code>false</code> if the change is denied by the
     *         {@link BeforeSelectionHandler}.
     */
    public boolean nextStep() {
        return nextStep(true);
    }

    /**
     * 
     * Go to back Step
     * 
     * @return <code>true</code> if successful, <code>false</code> if the change is denied by the
     *         {@link BeforeSelectionHandler}.
     */
    public boolean backStep() {
        return backStep(true);
    }

    /**
     * 
     * Select the given step but it will not fire the selection event
     * 
     * @return <code>true</code> if successful, <code>false</code> if the change is denied by the
     *         {@link BeforeSelectionHandler}.
     */

    public boolean selectStep(int index) {
        checkStepIndex(index);
        int currentIndex = -1;
        if (selected != null) {
            currentIndex = panel.getWidgetIndex(selected);
        }
        int diff = index - currentIndex;
        if (diff != 0) {
            if (diff > 0) {
                for (int ind = 0; ind < diff; ind++) {
                    nextStep(false);
                }
            } else {
                for (int ind = 0; ind > diff; ind--) {
                    backStep(false);
                }
            }
        }
        return false;
    }

    /**
     * 
     * Go to back Step
     * 
     * @param fireEvent
     *            Indicator to fire the selection event or not
     * 
     * @return <code>true</code> if successful, <code>false</code> if the change is denied by the
     *         {@link BeforeSelectionHandler}.
     */
    public boolean backStep(boolean fireEvents) {
        int currentlySelectedIndex = getSelectedStep();
        int index = currentlySelectedIndex - 1;
        checkStepIndex(index);
        if (fireEvents & !checkForBeforeSelectionEvent(index)) {
            return false;
        }

        if (currentlySelectedIndex > -1) {
            ClickDelegatePanel p = (ClickDelegatePanel) panel.getWidget(currentlySelectedIndex);
            p.removeStyleName(resource.css().active());
            p.addStyleName(resource.css().inactive());
        }

        if (currentlySelectedIndex > 1) {
            ClickDelegatePanel p = (ClickDelegatePanel) panel.getWidget(currentlySelectedIndex - 2);
            p.removeStyleName(resource.css().done());
            p.addStyleName(resource.css().lastDone());
        }

        selected = panel.getWidget(index);
        selected.removeStyleName(resource.css().inactive());
        selected.removeStyleName(resource.css().lastDone());
        selected.addStyleName(resource.css().active());
        if (index != (panel.getWidgetCount() - 1)) {
            panel.getWidget(panel.getWidgetCount() - 1).removeStyleName(resource.css().lastActiveElement());
        }
        if (fireEvents) {
            SelectionEvent.fire(this, index);
        }
        return true;
    }

    /**
     * 
     * @param fireEvents
     *            true to fire events, false not to
     * @return <code>true</code> if successful, <code>false</code> if the change is denied by the
     *         {@link BeforeSelectionHandler}.
     */
    public boolean nextStep(boolean fireEvents) {
        int currentlySelectedIndex = getSelectedStep();
        int index = currentlySelectedIndex + 1;
        checkStepIndex(index);
        if (fireEvents & !checkForBeforeSelectionEvent(index)) {
            return false;
        }

        if (currentlySelectedIndex > -1) {
            ClickDelegatePanel p = (ClickDelegatePanel) panel.getWidget(currentlySelectedIndex);
            p.removeStyleName(resource.css().active());
            p.addStyleName(resource.css().lastDone());
        }
        if (currentlySelectedIndex > 0) {
            ClickDelegatePanel p = (ClickDelegatePanel) panel.getWidget(currentlySelectedIndex - 1);
            p.removeStyleName(resource.css().lastDone());
            p.addStyleName(resource.css().done());
        }

        selected = panel.getWidget(index);
        selected.removeStyleName(resource.css().inactive());
        selected.addStyleName(resource.css().active());
        if (index == (panel.getWidgetCount() - 1)) {
            selected.addStyleName(resource.css().lastActiveElement());
        }
        if (fireEvents) {
            SelectionEvent.fire(this, index);
        }
        return true;
    }

    private boolean checkForBeforeSelectionEvent(int index) {

        BeforeSelectionEvent<?> event = BeforeSelectionEvent.fire(this, index);
        if (event != null && event.isCanceled()) {
            return false;
        }
        return true;
    }

    /**
     * Enable or disable a Step. When disabled, users cannot select the Step.
     * 
     * @param index
     *            the index of the Step to enable or disable
     * @param enabled
     *            true to enable, false to disable
     */
    public void setStepEnabled(int index, boolean enabled) {
        assert (index >= 0) && (index < getStepCount()) : "Step index out of bounds";

        ClickDelegatePanel delPanel = (ClickDelegatePanel) panel.getWidget(index);
        delPanel.setEnabled(enabled);
    }

    private void checkStepIndex(int index) {
        if ((index < -1) || (index >= getStepCount())) {
            throw new IndexOutOfBoundsException();
        }
    }

    public void removeAll() {
        int count = getStepCount();
        for (int index = 0; index < count; index++) {
            removeStep(0);
        }
    }
}