de.swm.commons.mobile.client.widgets.GenericRadioButtonGroup.java Source code

Java tutorial

Introduction

Here is the source code for de.swm.commons.mobile.client.widgets.GenericRadioButtonGroup.java

Source

/*
 * Copyright 2011 SWM Services GmbH.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package de.swm.commons.mobile.client.widgets;

import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.editor.client.IsEditor;
import com.google.gwt.editor.client.adapters.TakesValueEditor;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.text.shared.Renderer;
import com.google.gwt.user.client.ui.HasConstrainedValue;
import com.google.gwt.user.client.ui.HasEnabled;
import com.google.gwt.user.client.ui.Widget;
import de.swm.commons.mobile.client.SWMMobile;
import de.swm.commons.mobile.client.widgets.itf.IProvidesKeyAndValue;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

/**
 * Container for a group of {@link de.swm.commons.mobile.client.widgets.RadioButton}s.
 * Supports i18n-Enums as source for the radio button options.
 */
public class GenericRadioButtonGroup<T> extends CheckBoxGroup
        implements HasConstrainedValue<T>, IsEditor<TakesValueEditor<T>>, HasEnabled {

    private static final Logger LOGGER = Logger.getLogger(GenericRadioButtonGroup.class.getName());

    /**
     * Name for the button group.
     */
    private String myName = null;

    private final Map<Integer, String> indexKeyMap = new HashMap<Integer, String>();

    private final Map<String, Integer> keyIndexMap = new HashMap<String, Integer>();

    private IProvidesKeyAndValue<T> keyValueProvider;

    private Renderer<T> renderer;

    private TakesValueEditor<T> editor;

    private int lastIndex = 0;

    private T currentValue;

    private boolean enabled = true;

    /**
     * Default constructor.
     */
    public GenericRadioButtonGroup() {
        super();
        setStyleName(SWMMobile.getTheme().getMGWTCssBundle().getCheckRadioBoxCss().radioButtonGroup());
        addStyleName(SWMMobile.getTheme().getMGWTCssBundle().getCheckRadioBoxCss().vertical());
    }

    @Override
    public void onInitialLoad() {
        super.onInitialLoad();
        assert myName != null : "Attribute 'name' must be set on RadioButtonGroup";
    }

    @Override
    public void onClick(ClickEvent e) {
        if (!enabled) {
            return;
        }
        EventTarget target = e.getNativeEvent().getEventTarget();
        String targetTagName = ((Element) target.cast()).getTagName().toUpperCase();
        if (targetTagName.equals("SPAN")) {
            int before = getCheckedIndex();
            super.onClick(e);
            int after = getCheckedIndex();
            LOGGER.info("before " + before + " after " + after);
            if (after == -1) {
                RadioButton radio = (RadioButton) getWidget(before);
                if (!radio.getValue()) {
                    // cannot un-select a radio button without selecting another one.
                    radio.setValue(true);
                }
            } else if (before > -1) {
                RadioButton radio = (RadioButton) getWidget(before);
                radio.setValue(false);
            }
        } else if (targetTagName.equals("INPUT")) {
            super.onClick(e);
            for (int i = 0; i < myFlowPanel.getWidgetCount(); i++) {
                RadioButton radio = (RadioButton) getWidget(i);
                radio.setValue(radio.getValue());
            }
        }
    }

    /**
     * The widget index of first checked radio button.
     *
     * @return index
     */
    public int getCheckedIndex() {
        for (int i = 0; i < myFlowPanel.getWidgetCount(); i++) {
            RadioButton radio = (RadioButton) myFlowPanel.getWidget(i);
            if (radio.getValue()) {
                return i;
            }
        }
        return -1;
    }

    /**
     * Will return the first checked radio button or null if no {@link de.swm.commons.mobile.client.widgets.RadioButton} was checked.
     *
     * @return the checked widget
     */
    public RadioButton getCheckedWidget() {
        int i = getCheckedIndex();
        if (i > -1) {
            return (RadioButton) getWidget(i);
        }
        return null;
    }

    @Override
    public void add(Widget w) {
        assert w instanceof RadioButton : "Can only contain RadioButton widgets in RadioButtonGroup";
        RadioButton radio = (RadioButton) w;

        if (keyValueProvider != null) {
            if (this.keyValueProvider.getValue(radio.getFormValue()) != null) {
                T enumValue = this.keyValueProvider.getValue(radio.getFormValue());
                this.keyIndexMap.put(radio.getFormValue(), lastIndex);
                this.indexKeyMap.put(lastIndex, radio.getFormValue());
                radio.setText(renderer.render(enumValue));
                myFlowPanel.add(radio);
                lastIndex++;
            }
        } else {
            myFlowPanel.add(radio);
        }
        if (myName != null) {
            radio.setName(myName);
        }
        radio.addValueChangeHandler(this);
    }

    /**
     * Sets the name of the slideUpPanel.
     *
     * @param name the name
     */
    public void setName(String name) {
        myName = name;
        for (int i = 0; i < myFlowPanel.getWidgetCount(); i++) {
            RadioButton radio = (RadioButton) myFlowPanel.getWidget(i);
            radio.setName(myName);
        }
    }

    /**
     * Return the name of this button group.
     *
     * @return the name
     */
    public String getName() {
        return myName;
    }

    @Override
    public void setAcceptableValues(Collection<T> values) {
        // intentionally left empty
    }

    @Override
    public T getValue() {
        int index = getCheckedIndex();
        if (index >= 0) {
            if (keyValueProvider != null) {
                return this.keyValueProvider.getValue(this.indexKeyMap.get(index));
            } else {
                return (T) getCheckedWidget().getFormValue();
            }
        }
        return null;
    }

    @Override
    public void setValue(T value) {
        Integer indexToSelect;
        if (keyValueProvider != null) {
            indexToSelect = this.keyIndexMap.get(this.keyValueProvider.getKey(value));
            if (indexToSelect == null) {
                // index not found - reset all
                indexToSelect = -1;
            } else {
                // set selected radio button
                ((RadioButton) myFlowPanel.getWidget(indexToSelect)).setValue(true);
            }
            for (int i = 0; i < myFlowPanel.getWidgetCount(); i++) {
                // reset the rest
                if (i != indexToSelect) {
                    ((RadioButton) myFlowPanel.getWidget(i)).setValue(false);
                }
            }
        } else {
            // support String as Type T (shortcut)
            String stringValue = (String) value;
            for (int i = 0; i < myFlowPanel.getWidgetCount(); i++) {
                RadioButton radio = (RadioButton) myFlowPanel.getWidget(i);
                if (radio.getFormValue().equals(stringValue)) {
                    radio.setValue(true);
                    break;
                }
            }
        }
        this.currentValue = value;
    }

    @Override
    public void setValue(T value, boolean fireEvents) {
        final T oldValue = currentValue;
        setValue(value);
        if (fireEvents) {
            ValueChangeEvent.fireIfNotEqual(this, oldValue, value);
        }
    }

    @Override
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<T> handler) {
        return this.addHandler(handler, ValueChangeEvent.getType());
    }

    /**
     * KyValueProvider: the keyValueProvider to set.
     *
     * @param keyValueProvider the keyValueProvider to set
     */
    public void setKeyValueProvider(IProvidesKeyAndValue<T> keyValueProvider) {
        this.keyValueProvider = keyValueProvider;
    }

    /**
     * Renderer: the renderer to set.
     *
     * @param renderer the renderer to set
     */
    public void setRenderer(Renderer<T> renderer) {
        this.renderer = renderer;
    }

    @Override
    public TakesValueEditor<T> asEditor() {
        if (editor == null) {
            editor = TakesValueEditor.of(this);
        }
        return editor;
    }

    @Override
    public boolean isEnabled() {
        return this.enabled;
    }

    @Override
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
        for (int i = 0; i < myFlowPanel.getWidgetCount(); i++) {
            ((RadioButton) myFlowPanel.getWidget(i)).setEnabled(enabled);
        }
    }
}