/** * */ package com.googlecode.mgwt.ui.client.editor; import java.util.List; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.DivElement; import com.google.gwt.dom.client.Style.Display; import com.google.gwt.editor.client.EditorError; import com.google.gwt.editor.client.HasEditorErrors; import com.google.gwt.editor.client.IsEditor; import com.google.gwt.editor.ui.client.adapters.ValueBoxEditor; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiChild; import com.google.gwt.uibinder.client.UiConstructor; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.ValueBoxBase; import com.google.gwt.user.client.ui.Widget; import com.googlecode.mgwt.ui.client.widget.base.MValueBoxBase; import com.googlecode.mgwt.ui.client.widget.input.MTextBox; /** * This MValueBoxEditorDecorator is more or less a copy clone of * {@link ValueBoxEditor} and is needed to do JSR-303 BeanValidation. Only * difference is the child added here must be of type {@link MValueBoxBase}. * * <p> * <h3>Use in UiBinder Templates</h3> * <p> * The decorator may have exactly one {@link MValueBoxBase} added though an * <code><e:valuebox></code> child tag. * <p> * For example: * * <pre> * @UiField * MValueBoxEditorDecorator<String> name; * </pre> * * <pre> * <e:MValueBoxEditorDecorator ui:field='name'> * <e:mvaluebox> * <i:MTextBox /> * </e:mvaluebox> * </e:MValueBoxEditorDecorator> * </pre> * * @param <T> * the type which is edited, i.e. String for {@link MTextBox}. * * @author Christoph Guse * */ public class MValueBoxEditorDecorator<T> extends Composite implements HasEditorErrors<T>, IsEditor<ValueBoxEditor<T>> { interface Binder extends UiBinder<Widget, MValueBoxEditorDecorator<?>> { Binder BINDER = GWT.create(Binder.class); } private ValueBoxEditor<T> editor; @UiField SimplePanel contents; @UiField DivElement errorLabel; /** * Constructs a ValueBoxEditorDecorator, UI is taken from * MValueBoxEditorDecorator.ui.xml. */ @UiConstructor public MValueBoxEditorDecorator() { initWidget(Binder.BINDER.createAndBindUi(this)); } /** * Constructs a ValueBoxEditorDecorator using a {@link ValueBoxBase} widget * and a {@link ValueBoxEditor} editor. * * @param widget * the widget * @param editor * the editor */ public MValueBoxEditorDecorator(MValueBoxBase<T> widget, ValueBoxEditor<T> editor) { this(); contents.add(widget); this.editor = editor; } /** * Returns the associated {@link ValueBoxEditor}. * * @return a {@link ValueBoxEditor} instance * @see #setEditor(ValueBoxEditor) */ @Override public ValueBoxEditor<T> asEditor() { return editor; } /** * Sets the associated {@link ValueBoxEditor}. * * @param editor * a {@link ValueBoxEditor} instance * @see #asEditor() */ public void setEditor(ValueBoxEditor<T> editor) { this.editor = editor; } /** * Set the widget that the EditorPanel will display. This method will * automatically call {@link #setEditor}. * * @param widget * a {@link ValueBoxBase} widget */ @UiChild(limit = 1, tagname = "mvaluebox") public void setMValueBox(MValueBoxBase<T> widget) { contents.add(widget); setEditor(widget.asEditor()); } /** * The default implementation will display, but not consume, received errors * whose {@link EditorError#getEditor() getEditor()} method returns the * Editor passed into {@link #setEditor}. * * @param errors * a List of {@link EditorError} instances */ @Override public void showErrors(List<EditorError> errors) { StringBuilder sb = new StringBuilder(); for (EditorError error : errors) { if (error.getEditor().equals(editor)) { sb.append("\n").append(error.getMessage()); } } if (sb.length() == 0) { errorLabel.setInnerText(""); errorLabel.getStyle().setDisplay(Display.NONE); return; } errorLabel.setInnerText(sb.substring(1)); errorLabel.getStyle().setDisplay(Display.INLINE_BLOCK); } /** * Shows the given error message. * * @param errorMessage */ public void showError(String errorMessage) { errorLabel.setInnerText(errorMessage); errorLabel.getStyle().setDisplay(Display.INLINE_BLOCK); } }