org.bonitasoft.forms.client.view.widget.RadioButtonGroupWidget.java Source code

Java tutorial

Introduction

Here is the source code for org.bonitasoft.forms.client.view.widget.RadioButtonGroupWidget.java

Source

/**
 * Copyright (C) 2009 BonitaSoft S.A.
 * BonitaSoft, 31 rue Gustave Eiffel - 38000 Grenoble
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2.0 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.bonitasoft.forms.client.view.widget;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.bonitasoft.forms.client.model.ReducedFormFieldAvailableValue;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.HasValueChangeHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.Widget;

/**
 * Widget displaying a group of radio buttons (only one radio button can be selected inside a group)
 * 
 * @author Anthony Birembaut
 */
public class RadioButtonGroupWidget extends Composite
        implements HasClickHandlers, ClickHandler, HasValueChangeHandlers<Boolean>, ValueChangeHandler<Boolean> {

    protected static int radioButtonGroupIndex = 0;

    /**
     * Css class added to groupWidgets panel
     */
    private static final String GROUP_WIDGETS = "group-widgets";

    /**
     * the flow panel used to display the widget
     */
    protected FlowPanel inputDiv;

    /**
     * flow panel used to contain all the widget checkboxes
     */
    protected FlowPanel groupWidgets;

    /**
     * The set of radio buttons in the group
     */
    protected Set<RadioButton> radioButtons = new HashSet<RadioButton>();

    /**
     * items style
     */
    protected String itemsStyle;

    /**
     * The radio buttons group Id
     */
    protected String radioButtonGroupName;

    /**
     * click handlers registered for the widget
     */
    protected List<ClickHandler> clickHandlers;

    /**
     * value change handlers registered for the widget
     */
    protected List<ValueChangeHandler<Boolean>> valueChangeHandlers;

    /**
     * indicates if HTML is allowed as value of the widget
     */
    protected boolean allowHTML;

    /**
     * indicates if the widget instance is a child of a multiple element
     */
    protected boolean isElementOfMultipleWidget;

    /**
     * Constructor
     * 
     * @param radioButtonGroupId
     *            Id of the radio button group
     * @param availableValues
     *            available values of the group
     * @param initialValue
     *            initial value
     * @param itemsStyle
     *            the css classes of each radio button
     * @param allowHTML
     *            allow HTML in the radio buttons labels
     * 
     */
    public RadioButtonGroupWidget(final String radioButtonGroupId,
            final List<ReducedFormFieldAvailableValue> availableValues, final String initialValue,
            final String itemsStyle, final boolean allowHTML) {
        this(radioButtonGroupId, availableValues, initialValue, itemsStyle, allowHTML, false);
    }

    /**
     * Constructor
     * 
     * @param radioButtonGroupId
     *            Id of the radio button group
     * @param availableValues
     *            available values of the group
     * @param initialValue
     *            initial value
     * @param itemsStyle
     *            the css classes of each radio button
     * @param allowHTML
     *            allow HTML in the radio buttons labels
     * @param isElementOfMultipleWidget
     *            indicates if the widget instance is a child of a multiple element
     * 
     */
    public RadioButtonGroupWidget(final String radioButtonGroupId,
            final List<ReducedFormFieldAvailableValue> availableValues, final String initialValue,
            final String itemsStyle, final boolean allowHTML, final boolean isElementOfMultipleWidget) {

        this.itemsStyle = itemsStyle;
        this.allowHTML = allowHTML;
        this.isElementOfMultipleWidget = isElementOfMultipleWidget;
        inputDiv = new FlowPanel();
        groupWidgets = new FlowPanel();
        groupWidgets.addStyleName(GROUP_WIDGETS);
        radioButtonGroupName = getRadioButtonGroupName(radioButtonGroupId);

        for (final ReducedFormFieldAvailableValue availableValue : availableValues) {
            final RadioButton radioButton = createRadioButton(radioButtonGroupName, availableValue, allowHTML);
            addItemsStyle(radioButton, itemsStyle);
            setInitialValue(radioButton, initialValue, availableValue);
            groupWidgets.add(radioButton);
        }

        inputDiv.add(groupWidgets);
        initWidget(inputDiv);
    }

    private RadioButton createRadioButton(final String groupName,
            final ReducedFormFieldAvailableValue availableValue, final boolean allowHTML) {
        final RadioButton radioButton = new RadioButton(radioButtonGroupName, availableValue.getLabel(), allowHTML);
        radioButton.addClickHandler(this);
        radioButton.addValueChangeHandler(this);
        radioButton.setFormValue(availableValue.getValue());
        radioButton.setStyleName("bonita_form_radio");
        return radioButton;
    }

    private void addItemsStyle(final RadioButton radioButton, final String itemsStyle) {
        if (itemsStyle != null && itemsStyle.length() > 0) {
            radioButton.addStyleName(itemsStyle);
        }
    }

    private void setInitialValue(final RadioButton radioButton, final String initialValue,
            final ReducedFormFieldAvailableValue availableValue) {
        if (initialValue != null && initialValue.equals(availableValue.getValue())) {
            radioButton.setValue(true);
        }
    }

    /**
     * Useful in case the groups of radio buttons is displayed in several widget group instances
     * 
     * @param radioButtonGroupId
     *            the radio button definition Id
     * @return a name that can be used for the radio button group instance
     */
    protected String getRadioButtonGroupName(final String radioButtonGroupId) {

        String radioButtonGroupName = null;
        if (isElementOfMultipleWidget) {
            if (radioButtonGroupIndex == 0) {
                radioButtonGroupName = radioButtonGroupId;
            } else {
                radioButtonGroupName = radioButtonGroupId + Integer.toString(radioButtonGroupIndex);
            }
            radioButtonGroupIndex++;
        } else {
            radioButtonGroupName = radioButtonGroupId;
        }
        return radioButtonGroupName;
    }

    /**
     * @return the String value of the slected radio button of the group (null if no radio button is selected)
     */
    public String getValue() {

        String value = null;

        final Iterator<Widget> iterator = groupWidgets.iterator();
        while (iterator.hasNext()) {
            final RadioButton radioButton = (RadioButton) iterator.next();
            if (radioButton.getValue()) {
                value = radioButton.getFormValue();
                break;
            }
        }

        return value;
    }

    /**
     * Set the value of the widget
     * 
     * @param value
     */
    public void setValue(final String value, boolean fireEvents) {
        if (getValue() != null && getValue().equals(value) || value != null && value.equals(getValue())) {
            fireEvents = false;
        }
        for (final RadioButton radioButton : radioButtons) {
            if (value != null && value.equals(radioButton.getFormValue())) {
                radioButton.setValue(true);
            } else {
                radioButton.setValue(false);
            }
            if (fireEvents) {
                ValueChangeEvent.fire(radioButton, true);
            }
        }
    }

    /**
     * Set the wigdet available values
     * 
     * @param availableValues
     */
    public void setAvailableValues(final List<ReducedFormFieldAvailableValue> availableValues,
            final boolean fireEvents) {
        clearRadioButtons();
        for (final ReducedFormFieldAvailableValue availableValue : availableValues) {
            final RadioButton radioButton = createRadioButton(radioButtonGroupName, availableValue, allowHTML);
            addItemsStyle(radioButton, itemsStyle);
            saveRadioButton(radioButton);
            groupWidgets.add(radioButton);
        }
        if (fireEvents) {
            ValueChangeEvent.fire(this, true);
        }
    }

    private void saveRadioButton(final RadioButton radioButton) {
        radioButtons.add(radioButton);
    }

    private void clearRadioButtons() {
        radioButtons.clear();
        groupWidgets.clear();
    }

    /**
     * Enable or disable the radiobuttons group
     * 
     * @param isEnabled
     */
    public void setEnabled(final boolean isEnabled) {
        for (final RadioButton radioButton : radioButtons) {
            radioButton.setEnabled(isEnabled);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public HandlerRegistration addClickHandler(final ClickHandler clickHandler) {
        if (clickHandlers == null) {
            clickHandlers = new ArrayList<ClickHandler>();
        }
        clickHandlers.add(clickHandler);
        return new EventHandlerRegistration(clickHandler);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public HandlerRegistration addValueChangeHandler(final ValueChangeHandler<Boolean> valueChangeHandler) {
        if (valueChangeHandlers == null) {
            valueChangeHandlers = new ArrayList<ValueChangeHandler<Boolean>>();
        }
        valueChangeHandlers.add(valueChangeHandler);
        return new EventHandlerRegistration(valueChangeHandler);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onClick(final ClickEvent clickEvent) {
        if (clickHandlers != null) {
            for (final ClickHandler clickHandler : clickHandlers) {
                clickHandler.onClick(clickEvent);
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onValueChange(final ValueChangeEvent<Boolean> valueChangeEvent) {
        if (valueChangeHandlers != null) {
            for (final ValueChangeHandler<Boolean> valueChangeHandler : valueChangeHandlers) {
                valueChangeHandler.onValueChange(valueChangeEvent);
            }
        }
    }

    /**
     * Custom Handler registration
     */
    protected class EventHandlerRegistration implements HandlerRegistration {

        protected EventHandler eventHandler;

        public EventHandlerRegistration(final EventHandler eventHandler) {
            this.eventHandler = eventHandler;
        }

        @Override
        public void removeHandler() {
            if (eventHandler instanceof ClickHandler) {
                RadioButtonGroupWidget.this.clickHandlers.remove(eventHandler);
            } else if (eventHandler instanceof ValueChangeHandler<?>) {
                RadioButtonGroupWidget.this.valueChangeHandlers.remove(eventHandler);
            }
        }
    }
}