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