001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.gwt.client.ui.input; 029 030import org.opencms.gwt.client.I_CmsHasInit; 031import org.opencms.gwt.client.ui.I_CmsAutoHider; 032import org.opencms.gwt.client.ui.css.I_CmsInputLayoutBundle; 033import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; 034import org.opencms.gwt.client.ui.input.form.CmsWidgetFactoryRegistry; 035import org.opencms.gwt.client.ui.input.form.I_CmsFormWidgetFactory; 036import org.opencms.util.CmsPair; 037 038import java.util.HashMap; 039import java.util.List; 040import java.util.Map; 041 042import com.google.common.base.Optional; 043import com.google.gwt.event.logical.shared.HasValueChangeHandlers; 044import com.google.gwt.event.logical.shared.ValueChangeEvent; 045import com.google.gwt.event.logical.shared.ValueChangeHandler; 046import com.google.gwt.event.shared.GwtEvent; 047import com.google.gwt.event.shared.HandlerRegistration; 048import com.google.gwt.event.shared.SimpleEventBus; 049import com.google.gwt.user.client.ui.Composite; 050import com.google.gwt.user.client.ui.FlowPanel; 051import com.google.gwt.user.client.ui.Panel; 052 053/** 054 * Widget class consisting of a group of radio buttons, of which at most one may be active.<p> 055 * 056 * This is mostly a 'convenience widget' for creating and handling multiple radio buttons as a single widget. 057 * The radio buttons will be layed out vertically. If you need more control about the layout of the radio 058 * buttons, use multiple {@link CmsRadioButton} instances and link them with a {@link CmsRadioButtonGroup}.<p> 059 * 060 * @since 8.0.0 061 * 062 */ 063public class CmsRadioButtonGroupWidget extends Composite 064implements I_CmsFormWidget, HasValueChangeHandlers<String>, I_CmsHasInit { 065 066 /** The widget type identifier. */ 067 public static final String WIDGET_TYPE = "radio"; 068 069 /** The event bus. */ 070 protected SimpleEventBus m_eventBus; 071 072 /** The error display used by this widget. */ 073 private CmsErrorWidget m_error = new CmsErrorWidget(); 074 075 /** The radio button group for this radio button. */ 076 private CmsRadioButtonGroup m_group = new CmsRadioButtonGroup(); 077 078 /** The root panel containing all other components of this widget. */ 079 private Panel m_panel = new FlowPanel(); 080 081 /** A map which stores all radio buttons using their value as keys. */ 082 private Map<String, CmsRadioButton> m_radioButtons; 083 084 /** 085 * Creates a new instance from a list of key/value pairs.<p> 086 * 087 * The first component of each pair is the value of the radio buttons, the second component is used as the label. 088 * 089 * @param items a list of pairs of strings 090 */ 091 public CmsRadioButtonGroupWidget(List<CmsPair<String, String>> items) { 092 093 init(CmsPair.pairsToMap(items)); 094 } 095 096 /** 097 * Creates a new instance from a map of strings.<p> 098 * 099 * The keys of the map are used as the values of the radio buttons, and the values of the map are used as labels 100 * for the radio buttons. 101 * 102 * @param items the string map containing the select options 103 */ 104 public CmsRadioButtonGroupWidget(Map<String, String> items) { 105 106 init(items); 107 108 } 109 110 /** 111 * Initializes this class.<p> 112 */ 113 public static void initClass() { 114 115 // registers a factory for creating new instances of this widget 116 CmsWidgetFactoryRegistry.instance().registerFactory(WIDGET_TYPE, new I_CmsFormWidgetFactory() { 117 118 /** 119 * @see org.opencms.gwt.client.ui.input.form.I_CmsFormWidgetFactory#createWidget(java.util.Map, com.google.common.base.Optional) 120 */ 121 public I_CmsFormWidget createWidget(Map<String, String> widgetParams, Optional<String> defaultValue) { 122 123 return new CmsRadioButtonGroupWidget(widgetParams); 124 } 125 }); 126 } 127 128 /** 129 * @see com.google.gwt.event.logical.shared.HasValueChangeHandlers#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler) 130 */ 131 public HandlerRegistration addValueChangeHandler(final ValueChangeHandler<String> handler) { 132 133 return m_eventBus.addHandlerToSource(ValueChangeEvent.getType(), this, handler); 134 } 135 136 /** 137 * @see com.google.gwt.user.client.ui.Widget#fireEvent(com.google.gwt.event.shared.GwtEvent) 138 */ 139 @Override 140 public void fireEvent(GwtEvent<?> event) { 141 142 m_eventBus.fireEventFromSource(event, this); 143 } 144 145 /** 146 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#getApparentValue() 147 */ 148 public String getApparentValue() { 149 150 return getFormValueAsString(); 151 } 152 153 /** 154 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#getFieldType() 155 */ 156 public FieldType getFieldType() { 157 158 return I_CmsFormWidget.FieldType.STRING; 159 } 160 161 /** 162 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#getFormValue() 163 */ 164 public Object getFormValue() { 165 166 CmsRadioButton button = m_group.getSelectedButton(); 167 if (button == null) { 168 return ""; 169 } else { 170 return button.getName(); 171 } 172 } 173 174 /** 175 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#getFormValueAsString() 176 */ 177 public String getFormValueAsString() { 178 179 return (String)getFormValue(); 180 } 181 182 /** 183 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#isEnabled() 184 */ 185 public boolean isEnabled() { 186 187 boolean result = true; 188 for (Map.Entry<String, CmsRadioButton> entry : m_radioButtons.entrySet()) { 189 if (!entry.getValue().isEnabled()) { 190 result = false; 191 } 192 } 193 return result; 194 } 195 196 /** 197 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#reset() 198 */ 199 public void reset() { 200 201 m_group.deselectButton(); 202 } 203 204 /** 205 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#setAutoHideParent(org.opencms.gwt.client.ui.I_CmsAutoHider) 206 */ 207 public void setAutoHideParent(I_CmsAutoHider autoHideParent) { 208 209 // nothing to do 210 211 } 212 213 /** 214 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#setEnabled(boolean) 215 */ 216 public void setEnabled(boolean enabled) { 217 218 for (Map.Entry<String, CmsRadioButton> entry : m_radioButtons.entrySet()) { 219 entry.getValue().setEnabled(enabled); 220 } 221 } 222 223 /** 224 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#setErrorMessage(java.lang.String) 225 */ 226 public void setErrorMessage(String errorMessage) { 227 228 m_error.setText(errorMessage); 229 } 230 231 /** 232 * Sets the value of the widget.<p> 233 * 234 * @param value the new value 235 */ 236 public void setFormValue(Object value) { 237 238 if (value == null) { 239 value = ""; 240 } 241 242 if (value instanceof String) { 243 String strValue = (String)value; 244 if (strValue.equals("")) { 245 // interpret empty string as "no radio button selected" 246 reset(); 247 } else { 248 CmsRadioButton button = m_radioButtons.get(value); 249 m_group.selectButton(button); 250 } 251 } 252 } 253 254 /** 255 * @see org.opencms.gwt.client.ui.input.I_CmsFormWidget#setFormValueAsString(java.lang.String) 256 */ 257 public void setFormValueAsString(String formValue) { 258 259 setFormValue(formValue); 260 } 261 262 /** 263 * Internal method for initializing the widget with a list of select options.<p> 264 * 265 * @param items the list of select options 266 */ 267 protected void init(Map<String, String> items) { 268 269 initWidget(m_panel); 270 m_eventBus = new SimpleEventBus(); 271 m_radioButtons = new HashMap<String, CmsRadioButton>(); 272 for (Map.Entry<String, String> entry : items.entrySet()) { 273 274 final CmsRadioButton button = new CmsRadioButton(entry.getKey(), entry.getValue()); 275 button.setGroup(m_group); 276 m_radioButtons.put(entry.getKey(), button); 277 FlowPanel wrapper = new FlowPanel(); 278 wrapper.add(button); 279 m_panel.add(wrapper); 280 } 281 m_panel.add(m_error); 282 m_panel.setStyleName(I_CmsInputLayoutBundle.INSTANCE.inputCss().radioButtonGroup()); 283 m_panel.addStyleName(I_CmsLayoutBundle.INSTANCE.generalCss().textMedium()); 284 m_group.setValueChangeTarget(this); 285 } 286 287 /** 288 * Fires a ValueChangedEvent on this widget.<p> 289 * 290 * @param newValue the new value of this widget 291 */ 292 void fireValueChangedEvent(String newValue) { 293 294 ValueChangeEvent.fire(this, newValue); 295 } 296 297}