/** * 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.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; import org.bonitasoft.forms.client.model.FormFieldValue; import org.bonitasoft.forms.client.model.ReducedFormFieldAvailableValue; import org.bonitasoft.forms.client.model.ReducedFormSubtitle.SubTitlePosition; import org.bonitasoft.forms.client.model.ReducedFormWidget; import org.bonitasoft.forms.client.model.ReducedFormWidget.ItemPosition; import org.bonitasoft.forms.client.model.WidgetType; import org.bonitasoft.forms.client.view.SupportedFieldTypes; import org.bonitasoft.forms.client.view.common.URLUtils; import com.google.gwt.dom.client.Document; import com.google.gwt.event.dom.client.ChangeEvent; import com.google.gwt.event.dom.client.ChangeHandler; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.DomEvent; import com.google.gwt.event.dom.client.HasChangeHandlers; import com.google.gwt.event.dom.client.HasClickHandlers; import com.google.gwt.event.logical.shared.HasSelectionHandlers; import com.google.gwt.event.logical.shared.HasValueChangeHandlers; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; 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.i18n.client.DateTimeFormat; import com.google.gwt.i18n.client.DateTimeFormat.PredefinedFormat; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.CheckBox; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Focusable; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Hidden; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ListBox; import com.google.gwt.user.client.ui.MultiWordSuggestOracle; import com.google.gwt.user.client.ui.PasswordTextBox; import com.google.gwt.user.client.ui.PopupPanel; import com.google.gwt.user.client.ui.SuggestBox; import com.google.gwt.user.client.ui.SuggestBox.DefaultSuggestionDisplay; import com.google.gwt.user.client.ui.SuggestOracle.Suggestion; import com.google.gwt.user.client.ui.TextArea; import com.google.gwt.user.client.ui.TextBox; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.datepicker.client.DateBox; import com.google.gwt.user.datepicker.client.DateBox.DefaultFormat; import com.google.gwt.user.datepicker.client.DateBox.Format; /** * Generic form flow field widget * * @author Anthony Birembaut */ @SuppressWarnings("rawtypes") public class FormFieldWidget extends Composite implements HasChangeHandlers, ChangeHandler, HasClickHandlers, ClickHandler, HasValueChangeHandlers, ValueChangeHandler, HasSelectionHandlers<Suggestion>, SelectionHandler<Suggestion> { /** * the flow panel used to display the data field and its decorations */ protected FlowPanel flowPanel; /** * the container panel used to display the data field and its label */ protected FlowPanel fieldContainer; /** * the flow panel used to display the tooltip icon */ protected FlowPanel theOuterToolTipPanel; /** * The widget Id */ protected String widgetId; /** * widget field type */ protected WidgetType widgetType; /** * the value type */ protected String valueType; /** * the field ouput type */ protected String fieldOutputType; /** * the widget label */ private LabelWidget labelWidget; /** * the widget field */ protected Widget fieldWidget; /** * Date format for date picker */ protected DateTimeFormat displayFormat; /** * mandatory form field symbol */ protected String mandatoryFieldSymbol; /** * mandatory form field symbol classes */ protected String mandatoryFieldClasses; /** * the display format */ protected String displayFormatPattern; /** * The formID retrieved from the request as a String */ protected String formID = null; /** * The URL contextmap retrieved from the History taken */ protected Map<String, Object> contextMap; /** * Click handlers registered for the widget */ protected List<ClickHandler> clickHandlers; /** * Change handlers registered for the widget */ protected List<ChangeHandler> changeHandlers; /** * value change handlers registered for the widget */ protected Map<String, ValueChangeHandler<Serializable>> valueChangeHandlers; /** * selection handlers registered for the widget */ protected List<SelectionHandler<Suggestion>> selectionHandlers; /** * Map of suggestions for the suggestion box */ protected TreeMap<String, String> suggestionsMap; /** * Constructor * * @param widgetData * the widget data object * @param contextMap * @param mandatoryFieldSymbol * @param mandatoryFieldClasses */ public FormFieldWidget(final ReducedFormWidget widgetData, final Map<String, Object> contextMap, final String mandatoryFieldSymbol, final String mandatoryFieldClasses) { this(widgetData, widgetData.getInitialFieldValue(), contextMap, mandatoryFieldSymbol, mandatoryFieldClasses); } /** * Constructor * * @param widgetData * the widget data object * @param fieldValue * @param contextMap * @param mandatoryFieldSymbol * @param mandatoryFieldClasses */ public FormFieldWidget(final ReducedFormWidget widgetData, final FormFieldValue fieldValue, final Map<String, Object> contextMap, final String mandatoryFieldSymbol, final String mandatoryFieldClasses) { if (contextMap.get(URLUtils.FORM_ID) != null) { formID = (String) contextMap.get(URLUtils.FORM_ID); } this.contextMap = contextMap; this.mandatoryFieldSymbol = mandatoryFieldSymbol; this.mandatoryFieldClasses = mandatoryFieldClasses; init(widgetData, fieldValue); initWidget(flowPanel); createWidget(widgetData, fieldValue); } /** * Initialize the widget attributes * * @param widgetData * @param fieldValue */ protected void init(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { fieldContainer = new FlowPanel(); flowPanel = new FlowPanel(); widgetId = widgetData.getId(); widgetType = widgetData.getType(); displayFormatPattern = widgetData.getDisplayFormat(); valueType = fieldValue.getValueType(); fieldOutputType = widgetData.getFieldOutputType(); } /** * Create a {@link TextBox} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link TextBox} */ @SuppressWarnings("unchecked") protected TextBox createTextBox(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final TextBox textBox = new TextBox(); textBox.addChangeHandler(this); textBox.addValueChangeHandler(this); if (widgetData.getMaxLength() != 0) { textBox.setMaxLength(widgetData.getMaxLength()); } if (SupportedFieldTypes.JAVA_DATE_CLASSNAME.equals(valueType)) { textBox.setValue(getDateAsText(fieldValue)); } else { textBox.setValue(getStringValue(fieldValue)); } textBox.setEnabled(!widgetData.isReadOnly()); return textBox; } /** * Create a {@link TextArea} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link TextArea} */ @SuppressWarnings("unchecked") protected TextArea createTextArea(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final TextArea textArea = new TextArea(); textArea.addChangeHandler(this); textArea.addValueChangeHandler(this); if (widgetData.getMaxLength() != 0) { textArea.setCharacterWidth(widgetData.getMaxLength()); } if (widgetData.getMaxHeight() != 0) { textArea.setVisibleLines(widgetData.getMaxHeight()); } if (SupportedFieldTypes.JAVA_DATE_CLASSNAME.equals(valueType)) { textArea.setValue(getDateAsText(fieldValue)); } else { textArea.setValue(getStringValue(fieldValue)); } textArea.setEnabled(!widgetData.isReadOnly()); return textArea; } /** * Create a {@link RichTextWidget} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link RichTextWidget} */ protected RichTextWidget createRichTextArea(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final RichTextWidget richTextWidget = new RichTextWidget(); if (SupportedFieldTypes.JAVA_DATE_CLASSNAME.equals(valueType)) { richTextWidget.setValue(getDateAsText(fieldValue)); } else { richTextWidget.setValue(getStringValue(fieldValue)); } richTextWidget.setEnabled(!widgetData.isReadOnly()); return richTextWidget; } /** * Create a {@link PasswordTextBox} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link PasswordTextBox} */ @SuppressWarnings("unchecked") protected PasswordTextBox createPasswordTextBox(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final PasswordTextBox passwordTextBox = new PasswordTextBox(); passwordTextBox.addChangeHandler(this); passwordTextBox.addValueChangeHandler(this); if (widgetData.getMaxLength() != 0) { passwordTextBox.setMaxLength(widgetData.getMaxLength()); } passwordTextBox.setValue(getStringValue(fieldValue)); passwordTextBox.setEnabled(!widgetData.isReadOnly()); return passwordTextBox; } /** * Create a {@link HTML} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link HTML} */ protected HTML createText(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final HTML text = new HTML(); if (SupportedFieldTypes.JAVA_DATE_CLASSNAME.equals(valueType)) { text.setText(getDateAsText(fieldValue)); } else if (widgetData.allowHTMLInField()) { text.setHTML(getStringValue(fieldValue)); } else { text.setText(getStringValue(fieldValue)); } return text; } /** * Create a {@link CheckBox} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link CheckBox} */ @SuppressWarnings("unchecked") protected CheckBox createCheckBox(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final CheckBox checkBox = new CheckBox(); checkBox.addClickHandler(this); checkBox.addValueChangeHandler(this); try { checkBox.setValue((Boolean) fieldValue.getValue()); } catch (final Exception e) { Window.alert("initial value for checkbox " + widgetData.getId() + " should be a boolean."); checkBox.setValue(false, false); } checkBox.setEnabled(!widgetData.isReadOnly()); return checkBox; } /** * Create a {@link RadioButtonGroupWidget} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link RadioButtonGroupWidget} */ @SuppressWarnings("unchecked") protected RadioButtonGroupWidget createRadioButtonGroup(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final RadioButtonGroupWidget radioButtonGroupWidget = new RadioButtonGroupWidget(widgetData.getId(), widgetData.getAvailableValues(), getStringValue(fieldValue), widgetData.getItemsStyle(), widgetData.allowHTMLInField()); radioButtonGroupWidget.addClickHandler(this); radioButtonGroupWidget.addValueChangeHandler(this); radioButtonGroupWidget.setEnabled(!widgetData.isReadOnly()); return radioButtonGroupWidget; } /** * Create a {@link ListBox} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link ListBox} */ protected ListBox createListBox(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final ListBox listBox = new ListBox(false); listBox.addChangeHandler(this); int index = 0; final String fieldValueStr = getStringValue(fieldValue); for (final ReducedFormFieldAvailableValue availableValue : widgetData.getAvailableValues()) { listBox.addItem(availableValue.getLabel(), availableValue.getValue()); if (availableValue.getValue() != null && availableValue.getValue().equals(fieldValueStr)) { listBox.setItemSelected(index, true); } index++; } listBox.setEnabled(!widgetData.isReadOnly()); return listBox; } /** * Create a multiple select {@link ListBox} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link ListBox} */ protected ListBox createListBoxMulti(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final ListBox listBoxMulti = new ListBox(true); listBoxMulti.addChangeHandler(this); final Collection<String> initialValues = getStringValues(fieldValue); int indexMulti = 0; for (final ReducedFormFieldAvailableValue availableValue : widgetData.getAvailableValues()) { listBoxMulti.addItem(availableValue.getLabel(), availableValue.getValue()); if (initialValues != null) { for (final String value : initialValues) { if (availableValue.getValue() != null && availableValue.getValue().equals(value)) { listBoxMulti.setItemSelected(indexMulti, true); } } } indexMulti++; } if (widgetData.getMaxHeight() != 0) { listBoxMulti.setVisibleItemCount(widgetData.getMaxHeight()); } listBoxMulti.setEnabled(!widgetData.isReadOnly()); return listBoxMulti; } /** * Create a {@link SuggestBox} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link SuggestBox} */ @SuppressWarnings("unchecked") protected SuggestBox createSuggestBox(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final TextBox textBox = new TextBox(); textBox.setEnabled(!widgetData.isReadOnly()); final DefaultSuggestionDisplay suggestionDisplay = new DefaultSuggestionDisplay(); final String popupStyle = widgetData.getItemsStyle(); if (popupStyle != null && popupStyle.length() > 0) { suggestionDisplay.setPopupStyleName(popupStyle); } suggestionsMap = new TreeMap<String, String>(); final MultiWordSuggestOracle oracle = new MultiWordSuggestOracle(); // this fix the reordering of numbers final Comparator<String> numberComparator = new Comparator<String>() { @Override public int compare(final String o1, final String o2) { if (stringIsDouble(o1) && stringIsDouble(o2)) { return Double.valueOf(o1).compareTo(Double.valueOf(o2)); } return o1.compareTo(o2); } private boolean stringIsDouble(final String str) { return str.matches("^(([0-9]*)|(([0-9]*)[\\.,\\,]([0-9]*)))$"); } }; oracle.setComparator(numberComparator); String labelValue = null; final String fieldValueStr = getStringValue(fieldValue); widgetData.getAvailableValues(); for (final ReducedFormFieldAvailableValue availableValue : widgetData.getAvailableValues()) { final String label = availableValue.getLabel(); final String value = availableValue.getValue(); suggestionsMap.put(label, value); oracle.add(label); if (value != null && value.equals(fieldValueStr)) { labelValue = label; } } final SuggestBox suggestBox = new SuggestBox(oracle, textBox, suggestionDisplay); suggestBox.addValueChangeHandler(this); suggestBox.addSelectionHandler(this); if (labelValue != null) { suggestBox.setValue(labelValue); } else { suggestBox.setValue(fieldValueStr); } if (widgetData.getMaxItems() > 0) { suggestBox.setLimit(widgetData.getMaxItems() - 1); } return suggestBox; } /** * @param widgetData * @param fieldValue * @return a {@link AsyncSuggestBoxWidget} */ @SuppressWarnings("unchecked") protected AsyncSuggestBoxWidget createSuggestBoxAsync(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final AsyncSuggestBoxWidget formAsyncSuggestBoxWidget = new AsyncSuggestBoxWidget(widgetData, formID, contextMap, fieldValue); formAsyncSuggestBoxWidget.getAsyncSuggestBox().addValueChangeHandler(this); formAsyncSuggestBoxWidget.getAsyncSuggestBox().addSelectionHandler(this); return formAsyncSuggestBoxWidget; } /** * Create a {@link CheckboxGroupWidget} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link CheckboxGroupWidget} */ @SuppressWarnings("unchecked") protected CheckboxGroupWidget createCheckboxGroup(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final Collection<String> initialValues = getStringValues(fieldValue); final CheckboxGroupWidget checkBoxGroupWidget = new CheckboxGroupWidget(widgetData.getAvailableValues(), initialValues, widgetData.getItemsStyle(), widgetData.allowHTMLInField()); checkBoxGroupWidget.addClickHandler(this); checkBoxGroupWidget.addValueChangeHandler(this); checkBoxGroupWidget.setEnabled(!widgetData.isReadOnly()); return checkBoxGroupWidget; } /** * Create a {@link DateBox} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link DateBox} */ @SuppressWarnings("unchecked") protected DateBox createDateBox(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final DateBox dateBox = new DateBox(); dateBox.addValueChangeHandler(this); // display format if (displayFormatPattern != null && displayFormatPattern.length() > 0) { displayFormat = DateTimeFormat.getFormat(displayFormatPattern); } else { displayFormat = DateTimeFormat.getFormat(PredefinedFormat.DATE_LONG); } final Format format = new DefaultFormat(displayFormat); dateBox.setFormat(format); if (fieldValue.getValue() != null) { final Date initialDate = (Date) fieldValue.getValue(); dateBox.setValue(initialDate); } if (widgetData.isReadOnly()) { dateBox.getDatePicker().removeFromParent(); dateBox.getTextBox().setEnabled(false); } return dateBox; } /** * Create a {@link DurationWidget} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link DurationWidget} */ protected DurationWidget createDuration(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { Long duration = null; try { duration = (Long) fieldValue.getValue(); } catch (final Exception e) { duration = 0L; Window.alert("the initial value for duration widget " + widgetData.getId() + " should be a Long."); } final DurationWidget durationWidget = new DurationWidget(widgetData.getDisplayFormat(), duration, widgetData.getItemsStyle()); durationWidget.addChangeHandler(this); durationWidget.setEnabled(!widgetData.isReadOnly()); return durationWidget; } /** * Create a {@link FileUploadWidget} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link FileUploadWidget} */ protected FileUploadWidget createFileUpload(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final FileUploadWidget fileUploadWidget = new FileUploadWidget(formID, contextMap, widgetData.getId(), widgetData.getFileWidgetInputType(), fieldValue.getValueType(), fieldValue.getDocumentId(), fieldValue.getDocumentName(), getStringValue(fieldValue), widgetData.isDisplayAttachmentImage()); if (widgetData.isReadOnly()) { fileUploadWidget.disable(); } return fileUploadWidget; } /** * Create a {@link FileDownloadWidget} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link FileDownloadWidget} */ protected FileDownloadWidget createFileDownload(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { return new FileDownloadWidget(formID, contextMap, fieldValue.getValueType(), fieldValue.getDocumentId(), widgetData.isDisplayAttachmentImage(), getStringValue(fieldValue)); } /** * Create a {@link ImageWidget} widget * * @param widgetData * @param fieldValue * the widget value * @param displayAttachmentImage * @return a {@link ImageWidget} */ protected ImageWidget createImage(final ReducedFormWidget widgetData, final FormFieldValue fieldValue, final boolean displayAttachmentImage) { String value = null; if (displayAttachmentImage && SupportedFieldTypes.JAVA_FILE_CLASSNAME.equals(fieldValue.getValueType())) { value = fieldValue.getDocumentName(); } else { value = getStringValue(fieldValue); } return new ImageWidget(formID, contextMap, fieldValue.getValueType(), fieldValue.getDocumentId(), value, widgetData.getImageStyle(), displayAttachmentImage); } /** * Create an {@link TableWidget} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link TableWidget} */ @SuppressWarnings("unchecked") protected TableWidget createTable(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final TableWidget tableWidget = new TableWidget(widgetData, getTableValue(fieldValue)); tableWidget.addValueChangeHandler(this); return tableWidget; } /** * Create an {@link EditableGridWidget} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return an {@link EditableGridWidget} */ @SuppressWarnings("unchecked") protected EditableGridWidget createEditableGrid(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { final EditableGridWidget gridWidget = new EditableGridWidget(formID, widgetData, getGridValue(fieldValue)); gridWidget.addValueChangeHandler(this); return gridWidget; } /** * Create a {@link Hidden} widget * * @param widgetData * the widget data object * @param fieldValue * the widget value * @return a {@link Hidden} */ protected Hidden createHidden(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { return new Hidden(widgetData.getId(), getStringValue(fieldValue)); } /** * Create the widget * * @param widgetData * the widget data object */ protected void createWidget(final ReducedFormWidget widgetData, final FormFieldValue fieldValue) { // label creation if (widgetData.isMandatory() || widgetData.getLabel() != null && widgetData.getLabel().length() > 0) { labelWidget = new LabelWidget(widgetData, mandatoryFieldSymbol, mandatoryFieldClasses); if (ItemPosition.LEFT.equals(widgetData.getLabelPosition())) { addLabel(labelWidget, "bonita_form_label_left"); } else if (ItemPosition.TOP.equals(widgetData.getLabelPosition())) { addLabel(labelWidget, "bonita_form_label_top"); } } // field creation switch (widgetType) { case TEXTBOX: fieldWidget = createTextBox(widgetData, fieldValue); break; case TEXTAREA: fieldWidget = createTextArea(widgetData, fieldValue); break; case RICH_TEXTAREA: fieldWidget = createRichTextArea(widgetData, fieldValue); break; case PASSWORD: fieldWidget = createPasswordTextBox(widgetData, fieldValue); break; case TEXT: fieldWidget = createText(widgetData, fieldValue); break; case CHECKBOX: fieldWidget = createCheckBox(widgetData, fieldValue); break; case RADIOBUTTON_GROUP: fieldWidget = createRadioButtonGroup(widgetData, fieldValue); break; case LISTBOX_SIMPLE: fieldWidget = createListBox(widgetData, fieldValue); break; case LISTBOX_MULTIPLE: fieldWidget = createListBoxMulti(widgetData, fieldValue); break; case SUGGESTBOX: fieldWidget = createSuggestBox(widgetData, fieldValue); break; case SUGGESTBOX_ASYNC: fieldWidget = createSuggestBoxAsync(widgetData, fieldValue); break; case CHECKBOX_GROUP: fieldWidget = createCheckboxGroup(widgetData, fieldValue); break; case DATE: fieldWidget = createDateBox(widgetData, fieldValue); break; case DURATION: fieldWidget = createDuration(widgetData, fieldValue); break; case FILEUPLOAD: fieldWidget = createFileUpload(widgetData, fieldValue); break; case FILEDOWNLOAD: fieldWidget = createFileDownload(widgetData, fieldValue); break; case IMAGE: fieldWidget = createImage(widgetData, fieldValue, widgetData.isDisplayAttachmentImage()); break; case TABLE: fieldWidget = createTable(widgetData, fieldValue); break; case EDITABLE_GRID: fieldWidget = createEditableGrid(widgetData, fieldValue); break; case HIDDEN: fieldWidget = createHidden(widgetData, fieldValue); fieldContainer.add(fieldWidget); break; default: Window.alert(widgetType + " widget not supported."); break; } if (widgetType == WidgetType.LISTBOX_SIMPLE) { final FlowPanel div = new FlowPanel(); div.add(fieldWidget); addStandardWidgetFeatures(div, widgetData); div.addStyleName("list_container"); } else { addStandardWidgetFeatures(fieldWidget, widgetData); } if (labelWidget != null) { if (ItemPosition.RIGHT.equals(widgetData.getLabelPosition())) { addLabel(labelWidget, "bonita_form_label_right"); if (isStaticField()) { fieldWidget.addStyleName("bonita_form_static_field_left"); } else if (WidgetType.TEXTAREA.equals(widgetData.getType()) && widgetData.getMaxLength() != 0) { fieldWidget.addStyleName("bonita_form_field_left_no_width"); } else { fieldWidget.addStyleName("bonita_form_field_left"); } } else if (ItemPosition.BOTTOM.equals(widgetData.getLabelPosition())) { addLabel(labelWidget, "bonita_form_label_bottom"); if (isStaticField()) { fieldWidget.addStyleName("bonita_form_static_field_top"); } else if (WidgetType.TEXTAREA.equals(widgetData.getType()) && widgetData.getMaxLength() != 0) { fieldWidget.addStyleName("bonita_form_field_top_no_width"); } else { fieldWidget.addStyleName("bonita_form_field_top"); } } else if (ItemPosition.TOP.equals(widgetData.getLabelPosition())) { if (isStaticField()) { fieldWidget.addStyleName("bonita_form_static_field_bottom"); } else if (WidgetType.TEXTAREA.equals(widgetData.getType()) && widgetData.getMaxLength() != 0) { fieldWidget.addStyleName("bonita_form_field_bottom_no_width"); } else { fieldWidget.addStyleName("bonita_form_field_bottom"); } } else { if (isStaticField()) { fieldWidget.addStyleName("bonita_form_static_field_right"); } else if (WidgetType.TEXTAREA.equals(widgetData.getType()) && widgetData.getMaxLength() != 0) { fieldWidget.addStyleName("bonita_form_field_right_no_width"); } else { fieldWidget.addStyleName("bonita_form_field_right"); } } if (widgetData.getLabelStyle() != null && widgetData.getLabelStyle().length() > 0) { labelWidget.addStyleName(widgetData.getLabelStyle()); } } else { if (isStaticField()) { fieldWidget.addStyleName("bonita_form_static_field_top"); } else { fieldWidget.addStyleName("bonita_form_field_top"); } } if (widgetData.getInputStyle() != null && widgetData.getInputStyle().length() > 0) { fieldWidget.addStyleName(widgetData.getInputStyle()); } // display sub title if (widgetData.getSubtitle() != null) { final String label = widgetData.getSubtitle().getLabel(); if (label != null && label.trim().length() > 0) { if (SubTitlePosition.TOP.equals(widgetData.getSubtitle().getPosition())) { final HTML subTitle = new HTML(widgetData.getSubtitle().getLabel()); subTitle.addStyleName("bonita_form_field_sub_title"); flowPanel.add(subTitle); flowPanel.add(fieldContainer); } else { final HTML subTitle = new HTML(widgetData.getSubtitle().getLabel()); subTitle.addStyleName("bonita_form_field_sub_title"); flowPanel.add(fieldContainer); flowPanel.add(subTitle); } } else { flowPanel.add(fieldContainer); } } else { flowPanel.add(fieldContainer); } flowPanel.addStyleName("bonita_form_vertical_panel"); // tool-tip widget display if (widgetData.getPopupTooltip() != null && widgetData.getPopupTooltip().length() > 0) { theOuterToolTipPanel = new FlowPanel(); final PopupPanel toolTipPopupFrame = new PopupPanel(true); toolTipPopupFrame.setWidget(new Label(widgetData.getPopupTooltip())); toolTipPopupFrame.addStyleName("bonita_form_popup_tooltip"); final Image toolTipIcon = new Image("themeResource?theme=portal&location=images/tooltip.gif"); toolTipIcon.setStylePrimaryName("bonita_form_popup_tooltip_img"); theOuterToolTipPanel.add(toolTipIcon); theOuterToolTipPanel.setStylePrimaryName("bonita_form_popup_tooltip_icon"); toolTipIcon.addClickHandler(new ClickHandler() { @Override public void onClick(final ClickEvent event) { final Widget source = (Widget) event.getSource(); final int left = source.getAbsoluteLeft(); final int top = source.getAbsoluteTop(); toolTipPopupFrame.setPopupPosition(left + 10, top + 5); toolTipPopupFrame.show(); } }); if (ItemPosition.RIGHT.equals(widgetData.getLabelPosition())) { toolTipPopupFrame.addStyleName("bonita_form_popup_tooltip_left"); fieldContainer.add(theOuterToolTipPanel); } else if (ItemPosition.LEFT.equals(widgetData.getLabelPosition())) { fieldContainer.add(theOuterToolTipPanel); } else if (ItemPosition.TOP.equals(widgetData.getLabelPosition())) { fieldContainer.add(theOuterToolTipPanel); } else if (ItemPosition.BOTTOM.equals(widgetData.getLabelPosition())) { fieldContainer.add(theOuterToolTipPanel); } } } private void addLabel(final HTML labelWidget, final String styleName) { labelWidget.addStyleName(styleName); fieldContainer.add(labelWidget); } /** * @return true if the field is static, false otherwise */ protected boolean isStaticField() { if (widgetType.equals(WidgetType.TEXT) || widgetType.equals(WidgetType.FILEDOWNLOAD) || widgetType.equals(WidgetType.IMAGE)) { return true; } return false; } /** * Get the string display value for a date * * @param fieldValue * the field value object * @return the date as a String */ protected String getDateAsText(final FormFieldValue fieldValue) { if (displayFormatPattern != null && displayFormatPattern.length() > 0) { displayFormat = DateTimeFormat.getFormat(displayFormatPattern); } else { displayFormat = DateTimeFormat.getFormat(PredefinedFormat.DATE_LONG); } Date initialDate = null; if (fieldValue.getValue() != null) { initialDate = (Date) fieldValue.getValue(); } else { initialDate = new Date(); } return displayFormat.format(initialDate); } /** * @param fieldValue * the data field value * @return a List<String> */ @SuppressWarnings("unchecked") protected List<String> getTableValue(final FormFieldValue fieldValue) { List<String> valueList = null; try { valueList = (List<String>) fieldValue.getValue(); } catch (final ClassCastException firstAttemptException) { try { final Collection<String> tableValue = (Collection<String>) fieldValue.getValue(); valueList = new ArrayList<String>(tableValue); } catch (final ClassCastException secondAttemptException) { Window.alert("the initial value for table " + widgetId + " should be a Collection<String>."); } } return valueList; } /** * @param fieldValue * the data field value * @return a List of List<String> */ @SuppressWarnings("unchecked") protected List<List<String>> getGridValue(final FormFieldValue fieldValue) { List<List<String>> valueList = null; try { valueList = (List<List<String>>) fieldValue.getValue(); } catch (final Exception firstAttemptException) { try { valueList = new ArrayList<List<String>>(); final Collection<Collection<String>> tableValue = (Collection<Collection<String>>) fieldValue.getValue(); for (final Collection rowValue : tableValue) { valueList.add(new ArrayList<String>(rowValue)); } } catch (final Exception secondAttemptException) { Window.alert("the initial value for grid " + widgetId + " should be a Collection<Collection<String>>."); } } return valueList; } /** * Get the string display value for a date * * @param text * the widget data object * @return the date as a String */ protected Date getTextAsDate(final String text) { final DateTimeFormat initialFormat = DateTimeFormat.getFormat(displayFormatPattern); return initialFormat.parse(text); } /** * Get the string value of a {@link FormFieldValue} * * @param fieldValue * the {@link FormFieldValue} * @return a String */ protected String getStringValue(final FormFieldValue fieldValue) { String value = null; if (SupportedFieldTypes.JAVA_STRING_CLASSNAME.equals(fieldValue.getValueType())) { value = (String) fieldValue.getValue(); } else if (fieldValue.getValue() != null) { value = fieldValue.getValue().toString(); } return value; } /** * Get the Collection<String> value of a {@link FormFieldValue} * * @param fieldValue * the {@link FormFieldValue} * @return a Collection<String> */ @SuppressWarnings("unchecked") protected Collection<String> getStringValues(final FormFieldValue fieldValue) { Collection<String> value = null; try { value = (Collection<String>) fieldValue.getValue(); } catch (final Exception e) { Window.alert("the initial value for a checkbox or radiobutton group should be a Collection<String>."); value = new HashSet<String>(); } return value; } /** * add generic features to the field widgets * * @param fieldWidget * the GWT widget * @param widgetData * the widget data object */ protected void addStandardWidgetFeatures(final Widget fieldWidget, final ReducedFormWidget widgetData) { if (isStaticField()) { if (widgetType.equals(WidgetType.IMAGE)) { fieldWidget.setStyleName("bonita_form_image_container"); } else { fieldWidget.setStyleName("bonita_form_text"); } } else { fieldWidget.setStyleName("bonita_form_field"); if (widgetType.equals(WidgetType.DATE)) { fieldWidget.addStyleName("bonita_form_date"); } } if (widgetData.getTitle() != null && widgetData.getTitle().length() > 0) { fieldWidget.setTitle(widgetData.getTitle()); } insertWidgetInPanel(fieldWidget, widgetData); } /** * Insert the generated widget in the panel and set the fieldWidget attribute to keep a reference to it Set the HTML * attributes before inserting the generated widget in the panel. * * @param fieldWidget * the field widget * @param widgetData * the widget data object */ protected void insertWidgetInPanel(final Widget fieldWidget, final ReducedFormWidget widgetData) { final ElementAttributeSupport elementAttributeSupport = new ElementAttributeSupport(); elementAttributeSupport.addHtmlAttributes(fieldWidget, widgetData.getHtmlAttributes()); fieldContainer.add(fieldWidget); } /** * Retrieve the value of the field under the form of a {@link FormFieldValue} object. This conversion is needed because RPC * calls do not support the type 'Object'. * * @return a {@link FormFieldValue} object */ @SuppressWarnings("unchecked") public FormFieldValue getValue() { long attachmentId = -1; String attachmentName = null; Serializable value = null; String valueType = null; String format = null; String displayedValue = null; switch (widgetType) { case TEXTBOX: final TextBox textBox = (TextBox) fieldWidget; value = textBox.getValue(); valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; case TEXTAREA: final TextArea textArea = (TextArea) fieldWidget; value = textArea.getValue(); valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; case TEXT: final HTML text = (HTML) fieldWidget; value = text.getHTML(); valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; case RICH_TEXTAREA: final RichTextWidget richTextWidget = (RichTextWidget) fieldWidget; value = richTextWidget.getValue(); valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; case PASSWORD: final PasswordTextBox passwordTextBox = (PasswordTextBox) fieldWidget; value = passwordTextBox.getValue(); valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; case CHECKBOX: final CheckBox checkBox = (CheckBox) fieldWidget; value = checkBox.getValue(); valueType = SupportedFieldTypes.JAVA_BOOLEAN_CLASSNAME; break; case RADIOBUTTON_GROUP: final RadioButtonGroupWidget radioButtonGroupWidget = (RadioButtonGroupWidget) fieldWidget; value = radioButtonGroupWidget.getValue(); valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; case LISTBOX_SIMPLE: final ListBox listBox = (ListBox) fieldWidget; final int index = listBox.getSelectedIndex(); if (index > -1) { value = listBox.getValue(index); } valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; case LISTBOX_MULTIPLE: value = new ArrayList<String>(); final ListBox listBoxMulti = (ListBox) fieldWidget; for (int i = 0; i < listBoxMulti.getItemCount(); i++) { if (listBoxMulti.isItemSelected(i)) { ((List<String>) value).add(listBoxMulti.getValue(i)); } } valueType = SupportedFieldTypes.JAVA_COLLECTION_CLASSNAME; break; case SUGGESTBOX: final SuggestBox suggestBox = (SuggestBox) fieldWidget; displayedValue = suggestBox.getValue(); value = suggestionsMap.get(displayedValue); if (value == null) { value = displayedValue; } valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; case SUGGESTBOX_ASYNC: final AsyncSuggestBoxWidget formAsyncSuggestBoxWidget = (AsyncSuggestBoxWidget) fieldWidget; value = formAsyncSuggestBoxWidget.getValue(); valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; case CHECKBOX_GROUP: value = new ArrayList<String>(); final CheckboxGroupWidget checkboxGroupWidget = (CheckboxGroupWidget) fieldWidget; for (final String checkboxGroupValue : checkboxGroupWidget.getValue()) { ((List<String>) value).add(checkboxGroupValue); } valueType = SupportedFieldTypes.JAVA_COLLECTION_CLASSNAME; break; case DATE: final DateBox dateBox = (DateBox) fieldWidget; final String strValue = dateBox.getTextBox().getValue(); final Date dtValue = dateBox.getValue(); if (strValue != null && strValue.length() > 0 && dtValue == null) { value = strValue; valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; } else { value = dtValue; valueType = SupportedFieldTypes.JAVA_DATE_CLASSNAME; } break; case DURATION: final DurationWidget duration = (DurationWidget) fieldWidget; value = duration.getValue(); valueType = SupportedFieldTypes.JAVA_LONG_CLASSNAME; break; case FILEUPLOAD: final FileUploadWidget fileUpload = (FileUploadWidget) fieldWidget; attachmentName = fileUpload.getAttachmentName(); attachmentId = fileUpload.getAttachmentId(); value = fileUpload.getValue(); displayedValue = fileUpload.getDisplayedValue(); valueType = fileUpload.getValueType(); break; case TABLE: final TableWidget table = (TableWidget) fieldWidget; value = (Serializable) table.getValue(); valueType = SupportedFieldTypes.JAVA_COLLECTION_CLASSNAME; break; case EDITABLE_GRID: final EditableGridWidget grid = (EditableGridWidget) fieldWidget; value = (Serializable) grid.getValue(); valueType = SupportedFieldTypes.JAVA_COLLECTION_CLASSNAME; break; case HIDDEN: final Hidden hidden = (Hidden) fieldWidget; value = hidden.getValue(); valueType = SupportedFieldTypes.JAVA_STRING_CLASSNAME; break; default: break; } if (displayFormat != null) { format = displayFormat.getPattern(); } else { format = DateTimeFormat.getFormat(PredefinedFormat.DATE_LONG).getPattern(); } final FormFieldValue formFieldValue = new FormFieldValue(value, valueType, format, fieldOutputType); if (WidgetType.FILEUPLOAD.equals(widgetType)) { formFieldValue.setDocumentName(attachmentName); formFieldValue.setDocumentId(attachmentId); formFieldValue.setDisplayedValue(displayedValue); formFieldValue.setDocument(true); } return formFieldValue; } /** * @return Return the type of the widget */ public WidgetType getType() { return widgetType; } /** * Set the value of the widget * * @param fieldValue */ public void setValue(final FormFieldValue fieldValue) { if (fieldValue.getValue() != null) { Collection<String> values = null; boolean fireEvents = true; switch (widgetType) { case TEXTBOX: final TextBox textBox = (TextBox) fieldWidget; if (SupportedFieldTypes.JAVA_DATE_CLASSNAME.equals(fieldValue.getValueType())) { textBox.setValue(getDateAsText(fieldValue), fireEvents); } else { textBox.setValue(getStringValue(fieldValue), fireEvents); } break; case TEXTAREA: final TextArea textArea = (TextArea) fieldWidget; if (SupportedFieldTypes.JAVA_DATE_CLASSNAME.equals(fieldValue.getValueType())) { textArea.setValue(getDateAsText(fieldValue), fireEvents); } else { textArea.setValue(getStringValue(fieldValue), fireEvents); } break; case RICH_TEXTAREA: final RichTextWidget richTextWidget = (RichTextWidget) fieldWidget; if (SupportedFieldTypes.JAVA_DATE_CLASSNAME.equals(fieldValue.getValueType())) { richTextWidget.setValue(getDateAsText(fieldValue)); } else { richTextWidget.setValue(getStringValue(fieldValue)); } break; case TEXT: final HTML text = (HTML) fieldWidget; if (text.getHTML() != null && text.getHTML().equals(fieldValue.getValue()) || fieldValue.getValue() != null && fieldValue.getValue().equals(text.getHTML())) { fireEvents = false; } if (SupportedFieldTypes.JAVA_DATE_CLASSNAME.equals(fieldValue.getValueType())) { text.setText(getDateAsText(fieldValue)); } else { text.setHTML(getStringValue(fieldValue)); } if (fireEvents) { DomEvent.fireNativeEvent(Document.get().createChangeEvent(), text); } break; case PASSWORD: final PasswordTextBox passwordTextBox = (PasswordTextBox) fieldWidget; passwordTextBox.setValue(getStringValue(fieldValue), fireEvents); break; case CHECKBOX: final CheckBox checkBox = (CheckBox) fieldWidget; try { checkBox.setValue((Boolean) fieldValue.getValue(), fireEvents); } catch (final Exception e) { checkBox.setValue(false, fireEvents); Window.alert("initial value for checkbox " + widgetId + " should be a Boolean."); } break; case RADIOBUTTON_GROUP: final RadioButtonGroupWidget radioButtonGroupWidget = (RadioButtonGroupWidget) fieldWidget; radioButtonGroupWidget.setValue(getStringValue(fieldValue), fireEvents); break; case LISTBOX_SIMPLE: final ListBox listBox = (ListBox) fieldWidget; final int index = listBox.getSelectedIndex(); if (index < 0) { fireEvents = false; } else { if (listBox.getValue(index).equals(getStringValue(fieldValue))) { fireEvents = false; } } for (int i = 0; i < listBox.getItemCount(); i++) { if (listBox.getItemText(i).equals(getStringValue(fieldValue))) { listBox.setItemSelected(i, true); break; } } if (fireEvents) { DomEvent.fireNativeEvent(Document.get().createChangeEvent(), listBox); } break; case LISTBOX_MULTIPLE: final ListBox listBoxMulti = (ListBox) fieldWidget; values = getStringValues(fieldValue); boolean valueChanged = false; for (int i = 0; i < listBoxMulti.getItemCount(); i++) { if (values != null && values.contains(listBoxMulti.getItemText(i))) { if (!listBoxMulti.isItemSelected(i)) { valueChanged = true; listBoxMulti.setItemSelected(i, true); } } else { if (listBoxMulti.isItemSelected(i)) { valueChanged = true; listBoxMulti.setItemSelected(i, false); } } } if (fireEvents && valueChanged) { DomEvent.fireNativeEvent(Document.get().createChangeEvent(), listBoxMulti); } break; case SUGGESTBOX: final SuggestBox suggestBox = (SuggestBox) fieldWidget; final String stringValue = getStringValue(fieldValue); String labelValue = null; for (final Entry<String, String> suggestionEntry : suggestionsMap.entrySet()) { if (suggestionEntry.getValue() != null && suggestionEntry.getValue().equals(stringValue)) { labelValue = suggestionEntry.getKey(); } } if (labelValue != null) { suggestBox.setValue(labelValue, fireEvents); } else { suggestBox.setValue(stringValue, fireEvents); } break; case SUGGESTBOX_ASYNC: final AsyncSuggestBoxWidget formAsyncSuggestBoxWidget = (AsyncSuggestBoxWidget) fieldWidget; formAsyncSuggestBoxWidget.setValue(getStringValue(fieldValue), fireEvents); break; case CHECKBOX_GROUP: final CheckboxGroupWidget checkboxGroupWidget = (CheckboxGroupWidget) fieldWidget; values = getStringValues(fieldValue); checkboxGroupWidget.setValue(values, fireEvents); break; case DATE: final DateBox dateBox = (DateBox) fieldWidget; try { dateBox.setValue((Date) fieldValue.getValue(), fireEvents); } catch (final Exception e) { dateBox.setValue(null, fireEvents); Window.alert("initial value for date " + widgetId + " should be a Date."); } break; case DURATION: final DurationWidget durationWidget = (DurationWidget) fieldWidget; Long duration = null; try { duration = (Long) fieldValue.getValue(); } catch (final Exception e) { duration = 0L; Window.alert("The initial value for duration widget " + widgetId + " should be a Long."); } durationWidget.setValue(duration, fireEvents); break; case IMAGE: final ImageWidget image = (ImageWidget) fieldWidget; image.setValue(fieldValue.getDocumentId(), getStringValue(fieldValue), fireEvents); break; case TABLE: final TableWidget table = (TableWidget) fieldWidget; table.setValue(getTableValue(fieldValue), fireEvents); if (fireEvents) { DomEvent.fireNativeEvent(Document.get().createChangeEvent(), table); } break; case EDITABLE_GRID: final EditableGridWidget grid = (EditableGridWidget) fieldWidget; grid.setValue(getGridValue(fieldValue)); if (fireEvents) { DomEvent.fireNativeEvent(Document.get().createChangeEvent(), grid); } break; case HIDDEN: final Hidden hidden = (Hidden) fieldWidget; if (hidden.getValue() != null && hidden.getValue().equals(fieldValue.getValue()) || fieldValue.getValue() != null && fieldValue.getValue().equals(hidden.getValue())) { fireEvents = false; } hidden.setValue(getStringValue(fieldValue)); if (fireEvents) { DomEvent.fireNativeEvent(Document.get().createChangeEvent(), hidden); } break; default: Window.alert("The modification of the value of a " + widgetType + " widget is not supported."); break; } } } /** * Set the available values of the widget (for list widgets only) * * @param availableValues */ public void setAvailableValues(final List<ReducedFormFieldAvailableValue> availableValues, final boolean fireEvents) { switch (widgetType) { case RADIOBUTTON_GROUP: final RadioButtonGroupWidget radioButtonGroupWidget = (RadioButtonGroupWidget) fieldWidget; radioButtonGroupWidget.setAvailableValues(availableValues, fireEvents); break; case LISTBOX_SIMPLE: final ListBox listBox = (ListBox) fieldWidget; listBox.clear(); for (final ReducedFormFieldAvailableValue availableValue : availableValues) { listBox.addItem(availableValue.getLabel(), availableValue.getValue()); } if (fireEvents) { DomEvent.fireNativeEvent(Document.get().createChangeEvent(), listBox); } break; case LISTBOX_MULTIPLE: final ListBox listBoxMulti = (ListBox) fieldWidget; listBoxMulti.clear(); for (final ReducedFormFieldAvailableValue availableValue : availableValues) { listBoxMulti.addItem(availableValue.getLabel(), availableValue.getValue()); } if (fireEvents) { DomEvent.fireNativeEvent(Document.get().createChangeEvent(), listBoxMulti); } break; case SUGGESTBOX: final SuggestBox suggestBox = (SuggestBox) fieldWidget; final MultiWordSuggestOracle oracle = (MultiWordSuggestOracle) suggestBox.getSuggestOracle(); oracle.clear(); suggestionsMap.clear(); for (final ReducedFormFieldAvailableValue availableValue : availableValues) { suggestionsMap.put(availableValue.getLabel(), availableValue.getValue()); oracle.add(availableValue.getLabel()); } if (fireEvents) { DomEvent.fireNativeEvent(Document.get().createChangeEvent(), suggestBox); } break; case SUGGESTBOX_ASYNC: final AsyncSuggestBoxWidget formAsyncSuggestBoxWidget = (AsyncSuggestBoxWidget) fieldWidget; formAsyncSuggestBoxWidget.setAvailableValues(availableValues, fireEvents); break; case CHECKBOX_GROUP: final CheckboxGroupWidget checkboxGroupWidget = (CheckboxGroupWidget) fieldWidget; checkboxGroupWidget.setAvailableValues(availableValues, fireEvents); break; default: Window.alert("The modification of the available values of a " + widgetType + " widget is not supported."); break; } } /** * Set the available values of the widget (for table widgets only) * * @param newTableWidgetAvailableValues */ public void setTableAvailableValues(final List<List<ReducedFormFieldAvailableValue>> newTableWidgetAvailableValues, final boolean fireEvents) { if (WidgetType.TABLE.equals(widgetType)) { final TableWidget formTableWidget = (TableWidget) fieldWidget; formTableWidget.setAvailableValues(newTableWidgetAvailableValues, fireEvents); } else { Window.alert("The modification of the table available values of a " + widgetType + " widget is not supported."); } } /** * set the mandatory label * * @param mandatoryLabel */ public void setMandatoryLabel(final String mandatoryLabel) { labelWidget.setMandatoryText(mandatoryLabel); } /** * Set the focus on this widget if it's focusable */ public void setFocusOn() { if (fieldWidget instanceof Focusable) { ((Focusable) fieldWidget).setFocus(true); } } /** * @return the ID of the widget */ public String getId() { return widgetId; } /** * @return the field widget */ public Widget getFieldWidget() { return fieldWidget; } /** * {@inheritDoc} */ @Override public HandlerRegistration addChangeHandler(final ChangeHandler changeHandler) { if (changeHandlers == null) { changeHandlers = new ArrayList<ChangeHandler>(); } changeHandlers.add(changeHandler); return new EventHandlerRegistration(changeHandler); } /** * {@inheritDoc} */ @Override public HandlerRegistration addClickHandler(final ClickHandler clickHandler) { if (clickHandlers == null) { clickHandlers = new ArrayList<ClickHandler>(); } clickHandlers.add(clickHandler); return new EventHandlerRegistration(clickHandler); } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public HandlerRegistration addValueChangeHandler(final ValueChangeHandler valueChangeHandler) { if (valueChangeHandlers == null) { valueChangeHandlers = new HashMap<String, ValueChangeHandler<Serializable>>(); } if (valueChangeHandler != null) { valueChangeHandlers.put(String.valueOf(valueChangeHandler.hashCode()), valueChangeHandler); return new EventHandlerRegistration(valueChangeHandler); } else { throw new NullPointerException("the given ValueChangeHandler is not defined"); } } @Override public HandlerRegistration addSelectionHandler(final SelectionHandler<Suggestion> selectionHandler) { if (selectionHandlers == null) { selectionHandlers = new ArrayList<SelectionHandler<Suggestion>>(); } selectionHandlers.add(selectionHandler); return new EventHandlerRegistration(selectionHandler); } /** * {@inheritDoc} */ @Override public void onChange(final ChangeEvent changeEvent) { if (changeHandlers != null) { for (final ChangeHandler changeHandler : changeHandlers) { changeHandler.onChange(changeEvent); } } } /** * {@inheritDoc} */ @Override public void onClick(final ClickEvent clickEvent) { if (clickHandlers != null) { for (final ClickHandler clickHandler : clickHandlers) { clickHandler.onClick(clickEvent); } } } /** * {@inheritDoc} */ @Override @SuppressWarnings("unchecked") public void onValueChange(final ValueChangeEvent valueChangeEvent) { if (valueChangeHandlers != null) { for (final ValueChangeHandler valueChangeHandler : valueChangeHandlers.values()) { valueChangeHandler.onValueChange(valueChangeEvent); } } } /** * {@inheritDoc} */ @Override public void onSelection(final SelectionEvent<Suggestion> selectionEvent) { if (selectionHandlers != null) { for (final SelectionHandler<Suggestion> selectionHandler : selectionHandlers) { selectionHandler.onSelection(selectionEvent); } } } /** * 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) { clickHandlers.remove(eventHandler); } else if (eventHandler instanceof ChangeHandler) { changeHandlers.remove(eventHandler); } else if (eventHandler instanceof ValueChangeHandler) { valueChangeHandlers.remove(eventHandler); } else if (eventHandler instanceof SelectionHandler) { selectionHandlers.remove(eventHandler); } } } }