ingo@41: package de.intevation.flys.client.client.ui; ingo@41: ingo@41: import java.util.Map; ingo@41: ingo@41: import com.google.gwt.core.client.GWT; ingo@41: import com.google.gwt.i18n.client.NumberFormat; ingo@41: ingo@41: import com.smartgwt.client.types.TitleOrientation; ingo@41: import com.smartgwt.client.widgets.Canvas; ingo@41: import com.smartgwt.client.widgets.Label; ingo@41: import com.smartgwt.client.widgets.form.DynamicForm; ingo@41: import com.smartgwt.client.widgets.form.fields.events.BlurHandler; ingo@41: import com.smartgwt.client.widgets.form.fields.events.BlurEvent; ingo@41: import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; ingo@41: import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; ingo@41: import com.smartgwt.client.widgets.form.fields.FormItem; ingo@41: import com.smartgwt.client.widgets.form.fields.FloatItem; ingo@41: import com.smartgwt.client.widgets.form.fields.RadioGroupItem; ingo@41: import com.smartgwt.client.widgets.form.fields.TextItem; ingo@41: import com.smartgwt.client.widgets.layout.HLayout; ingo@41: import com.smartgwt.client.widgets.layout.VLayout; ingo@41: ingo@41: import de.intevation.flys.client.shared.model.Data; ingo@41: import de.intevation.flys.client.client.FLYSMessages; ingo@41: ingo@41: ingo@41: /** ingo@41: * This UIProvider creates a widget to enter locations or a distance. ingo@41: * ingo@41: * @author Ingo Weinzierl ingo@41: */ ingo@41: public class LocationDistancePanel ingo@41: extends AbstractUIProvider ingo@41: implements ChangeHandler, BlurHandler ingo@41: { ingo@41: /** The message class that provides i18n strings.*/ ingo@41: protected FLYSMessages MESSAGES = GWT.create(FLYSMessages.class); ingo@41: ingo@41: ingo@41: /** The constant name of the input field to enter locations.*/ ingo@41: public static final String FIELD_LOCATION = "location"; ingo@41: ingo@41: /** The constant name of the input field to enter the start of a distance.*/ ingo@41: public static final String FIELD_FROM = "from"; ingo@41: ingo@41: /** The constant name of the input field to enter the end of a distance.*/ ingo@41: public static final String FIELD_TO = "to"; ingo@41: ingo@41: /** The constant name of the input field to enter the step width of a ingo@41: * distance.*/ ingo@41: public static final String FIELD_WIDTH = "width"; ingo@41: ingo@41: ingo@41: /** The radio group for input mode selection.*/ ingo@41: protected RadioGroupItem radio; ingo@41: ingo@41: /** A container that will contain the location or the distance panel.*/ ingo@41: protected HLayout container; ingo@41: ingo@41: ingo@41: /** ingo@41: * Creates a new LocationDistancePanel instance. ingo@41: */ ingo@41: public LocationDistancePanel() { ingo@41: } ingo@41: ingo@41: ingo@41: /** ingo@41: * This method creates a widget that contains a label, a panel with ingo@41: * checkboxes to switch the input mode between location and distance input, ingo@41: * and a the mode specific panel. ingo@41: * ingo@41: * @param data The data that might be inserted. ingo@41: * ingo@41: * @return a panel. ingo@41: */ ingo@41: public Canvas create(Data data) { ingo@41: VLayout layout = new VLayout(); ingo@41: ingo@41: Label label = new Label(MESSAGES.location_distance_state()); ingo@41: container = new HLayout(); ingo@41: Canvas checkboxPanel = createRadioButtonPanel(); ingo@41: ingo@41: label.setHeight(25); ingo@41: ingo@41: layout.addMember(label); ingo@41: layout.addMember(checkboxPanel); ingo@41: layout.addMember(container); ingo@41: ingo@41: // TODO Add a table on the right to select locations by mouse click ingo@41: ingo@41: return layout; ingo@41: } ingo@41: ingo@41: ingo@41: /** ingo@41: * This method returns the selected data. ingo@41: * ingo@41: * @return the selected/inserted data. ingo@41: */ ingo@41: public Data[] getData() { ingo@41: // TODO Implement me ingo@41: ingo@41: return null; ingo@41: } ingo@41: ingo@41: ingo@41: /** ingo@41: * This method switches the input mode between location and distance input. ingo@41: * ingo@41: * @param event The click event fired by a RadioButtonGroupItem. ingo@41: */ ingo@41: public void onChange(ChangeEvent event) { ingo@41: String value = (String) event.getValue(); ingo@41: ingo@41: if (value == null) { ingo@41: return; ingo@41: } ingo@41: ingo@41: if (value.equals(MESSAGES.location())) { ingo@41: // TODO Insert correct values ingo@41: Canvas locationPanel = createLocationPanel(new double[] {1.7, 2.5}); ingo@41: container.removeMembers(container.getMembers()); ingo@41: container.addMember(locationPanel); ingo@41: } ingo@41: else if (value.equals(MESSAGES.distance())){ ingo@41: // TODO Insert correct values ingo@41: Canvas distancePanel = createDistancePanel(1.0, 3.4, 100); ingo@41: container.removeMembers(container.getMembers()); ingo@41: container.addMember(distancePanel); ingo@41: } ingo@41: } ingo@41: ingo@41: ingo@41: /** ingo@41: * This method is used to validate the inserted data in the form fields. ingo@41: * ingo@41: * @param event The BlurEvent that gives information about the FormItem that ingo@41: * has been modified and its value. ingo@41: */ ingo@41: public void onBlur(BlurEvent event) { ingo@41: FormItem item = event.getItem(); ingo@41: String field = item.getFieldName(); ingo@41: ingo@41: if (field == null) { ingo@41: return; ingo@41: } ingo@41: ingo@41: if (field.equals(FIELD_LOCATION)) { ingo@41: validateLocation(event.getForm(), item); ingo@41: } ingo@41: else if (field.equals(FIELD_FROM)) { ingo@41: validateDistance(event.getForm(), item); ingo@41: } ingo@41: else if (field.equals(FIELD_TO)) { ingo@41: validateDistance(event.getForm(), item); ingo@41: } ingo@41: else if (field.equals(FIELD_WIDTH)) { ingo@41: validateDistance(event.getForm(), item); ingo@41: } ingo@41: } ingo@41: ingo@41: ingo@41: /** ingo@41: * This method validates the entered text in the location input field. If ingo@41: * there are values that doesn't represent a valid location, an error is ingo@41: * displayed. ingo@41: * ingo@41: * @param form The DynamicForm. ingo@41: * @param item The FormItem. ingo@41: */ ingo@41: protected void validateLocation(DynamicForm form, FormItem item) { ingo@41: String value = (String) item.getValue(); ingo@41: String[] parts = value.split(" "); ingo@41: ingo@41: if (parts == null) { ingo@41: return; ingo@41: } ingo@41: ingo@41: NumberFormat f = NumberFormat.getDecimalFormat(); ingo@41: Map errors = form.getErrors(); ingo@41: ingo@41: try { ingo@41: for (String part: parts) { ingo@41: double location = f.parse(part); ingo@41: ingo@41: // TODO save the location ingo@41: } ingo@41: ingo@41: errors.remove(item.getFieldName()); ingo@41: } ingo@41: catch (NumberFormatException nfe) { ingo@41: errors.put(item.getFieldName(), MESSAGES.wrongFormat()); ingo@41: } ingo@41: ingo@41: form.setErrors(errors, true); ingo@41: } ingo@41: ingo@41: ingo@41: /** ingo@41: * This method validates the entered text in the distance input fields. If ingo@41: * there are values that doesn't represent a valid float, an error is ingo@41: * displayed. ingo@41: * ingo@41: * @param form The DynamicForm. ingo@41: * @param item The FormItem. ingo@41: */ ingo@41: protected void validateDistance(DynamicForm form, FormItem item) { ingo@41: String v = (String) item.getValue(); ingo@41: ingo@41: NumberFormat f = NumberFormat.getDecimalFormat(); ingo@41: Map errors = form.getErrors(); ingo@41: ingo@41: try { ingo@41: double value = f.parse(v); ingo@41: ingo@41: // TODO SAVE THE VALUE ingo@41: ingo@41: errors.remove(item.getFieldName()); ingo@41: } ingo@41: catch (NumberFormatException nfe) { ingo@41: errors.put(item.getFieldName(), MESSAGES.wrongFormat()); ingo@41: ingo@41: item.focusInItem(); ingo@41: } ingo@41: ingo@41: form.setErrors(errors, true); ingo@41: } ingo@41: ingo@41: ingo@41: /** ingo@41: * This method creates the panel that contains the checkboxes to switch ingo@41: * between the input mode 'location' and 'distance'. ingo@41: * ingo@41: * @return the checkbox panel. ingo@41: */ ingo@41: protected Canvas createRadioButtonPanel() { ingo@41: DynamicForm form = new DynamicForm(); ingo@41: ingo@41: radio = new RadioGroupItem("mode"); ingo@41: radio.setShowTitle(false); ingo@41: radio.setVertical(false); ingo@41: radio.setValueMap(MESSAGES.location(), MESSAGES.distance()); ingo@41: ingo@41: radio.addChangeHandler(this); ingo@41: ingo@41: form.setFields(radio); ingo@41: ingo@41: return form; ingo@41: } ingo@41: ingo@41: ingo@41: /** ingo@41: * This method creates the location panel. It contains just a single input ingo@41: * field. ingo@41: * ingo@41: * @param locations For each location a double value ingo@41: * ingo@41: * @return a panel with an input field. ingo@41: */ ingo@41: protected Canvas createLocationPanel(double[] locations) { ingo@41: TextItem ti = new TextItem(FIELD_LOCATION); ingo@41: ingo@41: ti.setTitle(MESSAGES.unitLocation()); ingo@41: ti.addBlurHandler(this); ingo@41: ingo@41: NumberFormat f = NumberFormat.getDecimalFormat(); ingo@41: ingo@41: StringBuilder text = new StringBuilder(); ingo@41: boolean firstItem = true; ingo@41: ingo@41: for (double loc: locations) { ingo@41: if (!firstItem) { ingo@41: text.append(" "); ingo@41: } ingo@41: ingo@41: text.append(f.format(loc)); ingo@41: ingo@41: firstItem = false; ingo@41: } ingo@41: ingo@41: ti.setValue(text.toString()); ingo@41: ingo@41: // TODO There is still a colon between the input field and the text - ingo@41: // remove this colon! ingo@41: ingo@41: DynamicForm form = new DynamicForm(); ingo@41: form.setFields(ti); ingo@41: form.setTitleOrientation(TitleOrientation.RIGHT); ingo@41: form.setNumCols(2); ingo@41: ingo@41: return form; ingo@41: } ingo@41: ingo@41: ingo@41: /** ingo@41: * This method creates the distance panel. It contains three input fields: ingo@41: * one for a start, one for the end and one for a step width. ingo@41: * ingo@41: * @param start The start point. ingo@41: * @param end The end point. ingo@41: * @param sw The step width. ingo@41: * ingo@41: * @return a panel with three input fields. ingo@41: */ ingo@41: protected Canvas createDistancePanel(double start,double end,double sw) { ingo@41: FloatItem from = new FloatItem(FIELD_FROM); ingo@41: FloatItem to = new FloatItem(FIELD_TO); ingo@41: FloatItem width = new FloatItem(FIELD_WIDTH); ingo@41: ingo@41: from.addBlurHandler(this); ingo@41: to.addBlurHandler(this); ingo@41: width.addBlurHandler(this); ingo@41: ingo@41: // TODO There is still a colon between the input field and the text - ingo@41: // remove this colon! ingo@41: ingo@41: NumberFormat f = NumberFormat.getDecimalFormat(); ingo@41: ingo@41: from.setValue(f.format(start)); ingo@41: to.setValue(f.format(end)); ingo@41: width.setValue(f.format(sw)); ingo@41: ingo@41: from.setWidth(50); ingo@41: to.setWidth(50); ingo@41: width.setWidth(50); ingo@41: ingo@41: from.setTitle(MESSAGES.unitFrom()); ingo@41: to.setTitle(MESSAGES.unitTo()); ingo@41: width.setTitle(MESSAGES.unitWidth()); ingo@41: ingo@41: DynamicForm form = new DynamicForm(); ingo@41: form.setFields(from, to, width); ingo@41: form.setTitleOrientation(TitleOrientation.RIGHT); ingo@41: form.setNumCols(6); ingo@41: form.setFixedColWidths(false); ingo@41: ingo@41: return form; ingo@41: } ingo@41: } ingo@41: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :