Mercurial > dive4elements > river
view gwt-client/src/main/java/org/dive4elements/river/client/client/ui/LocationDistancePanel.java @ 9698:812a6a3eaaf5
another try
author | dnt_bjoernsen <d.tironi@bjoernsen.de> |
---|---|
date | Wed, 20 Jan 2021 17:19:59 +0100 |
parents | 7337034eb5d5 |
children |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.client.client.ui; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import org.dive4elements.river.client.client.Config; import org.dive4elements.river.client.client.FLYSConstants; import org.dive4elements.river.client.client.event.FilterHandler; import org.dive4elements.river.client.client.event.RangeFilterEvent; import org.dive4elements.river.client.client.event.StringFilterEvent; import org.dive4elements.river.client.client.services.DistanceInfoService; import org.dive4elements.river.client.client.services.DistanceInfoServiceAsync; import org.dive4elements.river.client.client.ui.range.DistanceInfoDataSource; import org.dive4elements.river.client.shared.model.ArtifactDescription; import org.dive4elements.river.client.shared.model.Data; import org.dive4elements.river.client.shared.model.DataItem; import org.dive4elements.river.client.shared.model.DataList; import org.dive4elements.river.client.shared.model.DefaultData; import org.dive4elements.river.client.shared.model.DefaultDataItem; import org.dive4elements.river.client.shared.model.DistanceInfoObject; import com.google.gwt.core.client.GWT; import com.google.gwt.i18n.client.NumberFormat; import com.smartgwt.client.data.AdvancedCriteria; import com.smartgwt.client.data.Criteria; import com.smartgwt.client.data.Criterion; import com.smartgwt.client.data.Record; import com.smartgwt.client.types.Alignment; import com.smartgwt.client.types.ListGridFieldType; import com.smartgwt.client.types.OperatorId; 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.FormItem; import com.smartgwt.client.widgets.form.fields.RadioGroupItem; import com.smartgwt.client.widgets.form.fields.SelectItem; import com.smartgwt.client.widgets.form.fields.StaticTextItem; import com.smartgwt.client.widgets.form.fields.events.BlurEvent; import com.smartgwt.client.widgets.form.fields.events.BlurHandler; import com.smartgwt.client.widgets.form.fields.events.ChangeEvent; import com.smartgwt.client.widgets.form.fields.events.ChangeHandler; import com.smartgwt.client.widgets.form.fields.events.ChangedEvent; import com.smartgwt.client.widgets.form.fields.events.ChangedHandler; import com.smartgwt.client.widgets.grid.CellFormatter; import com.smartgwt.client.widgets.grid.ListGrid; import com.smartgwt.client.widgets.grid.ListGridField; import com.smartgwt.client.widgets.grid.ListGridRecord; import com.smartgwt.client.widgets.grid.events.RecordClickEvent; import com.smartgwt.client.widgets.grid.events.RecordClickHandler; import com.smartgwt.client.widgets.layout.HLayout; import com.smartgwt.client.widgets.layout.VLayout; import com.smartgwt.client.widgets.tab.Tab; import com.smartgwt.client.widgets.tab.TabSet; import com.smartgwt.client.widgets.tab.events.TabSelectedEvent; import com.smartgwt.client.widgets.tab.events.TabSelectedHandler; /** * 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, FilterHandler { private static final long serialVersionUID = -10820092176039372L; /** The message class that provides i18n strings. */ protected FLYSConstants MESSAGES = GWT.create(FLYSConstants.class); /** The DistanceInfoService used to retrieve locations about rivers. */ protected DistanceInfoServiceAsync distanceInfoService = GWT.create(DistanceInfoService.class); public static final String FIELD_MODE = "mode"; /** 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 locations. */ public static final String FIELD_VALUE_LOCATION = "location"; /** The constant name of the input field to enter distance. */ public static final String FIELD_VALUE_DISTANCE = "distance"; /** * The constant name of the input field to enter the step width of a * distance. */ public static final String FIELD_WIDTH = "width"; public static final int WIDTH = 250; /** The radio group for input mode selection. */ protected DynamicForm mode; /** A container that will contain the location or the distance panel. */ protected HLayout container; /** The min value for a distance. */ protected double min; /** The max value for a distance. */ protected double max; /** The 'from' value entered in the distance mode. */ protected double from; /** The 'to' value entered in the distance mode. */ protected double to; /** The 'step' value entered in the distance mode. */ protected double step; /** The values entered in the location mode. */ protected double[] values; /** The input panel for locations. */ protected DoubleArrayPanel locationPanel; /** The input panel for distances. */ protected DoubleRangePanel distancePanel; /** The tab set containing the location and distance table. */ protected TabSet inputTables; /** The distance table. */ protected ListGrid distanceTable; /** The locations table. */ protected ListGrid locationsTable; /** The table data. */ protected DistanceInfoObject[] tableData; /** The table filter. */ protected TableFilter filterDescription; protected RangeTableFilter filterRange; /** The Combobox for table filter criteria. */ protected SelectItem filterCriteria; protected StaticTextItem filterResultCount; protected ListGrid currentFiltered; /** * Creates a new LocationDistancePanel instance. */ public LocationDistancePanel() { this.distanceTable = new ListGrid(); this.distanceTable.setAutoFetchData(true); this.locationsTable = new ListGrid(); this.locationsTable.setAutoFetchData(true); this.distanceTable.setShowHeaderContextMenu(false); this.locationsTable.setShowHeaderContextMenu(false); } /** * 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. */ @Override public Canvas create(final DataList data) { final VLayout layout = new VLayout(); layout.setMembersMargin(10); final Label label = getLabel(data);// new Label(MESSAGES.location_distance_state()); final Canvas widget = createWidget(data); final Canvas submit = getNextButton(); createDistanceInputPanel(); initDefaults(data); widget.setHeight(50); label.setHeight(25); layout.addMember(label); layout.addMember(widget); layout.addMember(submit); return layout; } protected Label getLabel(final DataList data) { final Data item = data.get(0); return new Label(item.getDescription());// // TODO: migrate distance_part_state to server // item.getDescription()); // holt das Label vom Server (funktoniert schon sehr oft so!) } /** * Setup a table for a DistanceInfoDataSource. * * Sets up a table to for input completion. The table * can be used either for single locations or distances. * Depending on the value of isDistance the table will * have a to and a from column or a single location column. * * @param table * the ListGrid to set up. * @param doublePins * wether or not to have. * @param isDistance * wether or not to and from should be included. */ protected void setupDistanceInfoTable(final ListGrid table, final boolean doublePins, final boolean isDistance) { final String baseUrl = GWT.getHostPageBaseURL(); table.setWidth100(); table.setShowRecordComponents(true); table.setShowRecordComponentsByCell(true); table.setHeight100(); table.setEmptyMessage(this.MESSAGES.empty_filter()); table.setCanReorderFields(false); final CellFormatter cf = new CellFormatter() { @Override public String format(final Object value, final ListGridRecord record, final int rowNum, final int colNum) { if (value == null) return null; try { NumberFormat nf; final double v = Double.parseDouble((String) value); nf = NumberFormat.getFormat("###0.00##"); return nf.format(v); } catch (final Exception e) { return value.toString(); } } }; ListGridField pin1 = null; ListGridField pin2 = null; if (doublePins) { pin1 = new ListGridField("fromIcon", this.MESSAGES.from()); pin1.setWidth(30); } else { pin1 = new ListGridField("fromIcon", this.MESSAGES.selection()); pin1.setWidth(60); } pin1.setType(ListGridFieldType.ICON); pin1.setCellIcon(baseUrl + this.MESSAGES.markerGreen()); if (doublePins) { pin2 = new ListGridField("toIcon", this.MESSAGES.to()); pin2.setType(ListGridFieldType.ICON); pin2.setWidth(30); pin2.setCellIcon(baseUrl + this.MESSAGES.markerRed()); } if (isDistance) { /* We have from / to fields */ pin1.addRecordClickHandler(new RecordClickHandler() { @Override public void onRecordClick(final RecordClickEvent e) { final Record r = e.getRecord(); if (!isLocationMode()) { /* distance panel and distance mode */ setFrom(r.getAttribute("from")); setTo(r.getAttribute("to")); } else { /* distance panel and location mode */ /* Pin 1 is the "from" pin */ appendLocation(r.getAttribute("from")); } } }); if (doublePins) { pin2.addRecordClickHandler(new RecordClickHandler() { @Override public void onRecordClick(final RecordClickEvent e) { final Record r = e.getRecord(); if (isLocationMode()) { appendLocation(r.getAttribute("to")); } else { /* * Distance and double pin behavior is only * defined for location mode. */ GWT.log("Unhandled input state."); } } }); } } else { /* We only have the from field */ pin1.addRecordClickHandler(new RecordClickHandler() { @Override public void onRecordClick(final RecordClickEvent e) { final Record r = e.getRecord(); if (!isLocationMode()) { /* Location panel and distance mode */ setFrom(r.getAttribute("from")); } else { /* Location panel and location mode */ appendLocation(r.getAttribute("from")); } } }); if (doublePins) { pin2.addRecordClickHandler(new RecordClickHandler() { @Override public void onRecordClick(final RecordClickEvent e) { final Record r = e.getRecord(); if (!isLocationMode()) { setTo(r.getAttribute("from")); } else { /* * Distance and double pin behavior is only * defined for location mode. */ GWT.log("Unhandled input state."); } } }); } } final ListGridField ddescr = new ListGridField("description", this.MESSAGES.description()); ddescr.setType(ListGridFieldType.TEXT); ddescr.setWidth("*"); ListGridField from; ListGridField to = null; if (isDistance) { from = new ListGridField("from", this.MESSAGES.from()); to = new ListGridField("to", this.MESSAGES.to()); to.setType(ListGridFieldType.FLOAT); to.setCellFormatter(cf); to.setWidth("12%"); to.setAlign(Alignment.LEFT); } else { from = new ListGridField("from", this.MESSAGES.locations()); } from.setCellFormatter(cf); from.setWidth("12%"); final ListGridField dside = new ListGridField("riverside", this.MESSAGES.riverside()); dside.setType(ListGridFieldType.TEXT); dside.setWidth("12%"); final ListGridField bottom = new ListGridField("bottom", this.MESSAGES.bottom_edge()); bottom.setType(ListGridFieldType.TEXT); bottom.setWidth("10%"); bottom.setCellFormatter(cf); final ListGridField top = new ListGridField("top", this.MESSAGES.top_edge()); top.setType(ListGridFieldType.TEXT); top.setWidth("10%"); top.setCellFormatter(cf); if (doublePins && isDistance) { table.setFields(pin1, pin2, ddescr, from, to, dside, bottom, top); } else if (doublePins) { table.setFields(pin1, pin2, ddescr, from, dside, bottom, top); } else if (isDistance) { table.setFields(pin1, ddescr, from, to, dside, bottom, top); } else { table.setFields(pin1, ddescr, from, dside, bottom, top); } } @Override public Canvas createOld(final DataList dataList) { final List<Data> items = dataList.getAll(); final Data dMode = getData(items, "ld_mode"); final DataItem[] dItems = dMode.getItems(); boolean rangeMode = true; if (dItems != null && dItems[0] != null) { rangeMode = FIELD_VALUE_DISTANCE.equals(dItems[0].getStringValue()); } final HLayout layout = new HLayout(); layout.setWidth("400px"); final Label label = new Label(dataList.getLabel()); label.setWidth("200px"); final Canvas back = getBackButton(dataList.getState()); layout.addMember(label); if (rangeMode) { layout.addMember(getOldRangeSelection(dataList)); } else { layout.addMember(getOldLocationSelection(dataList)); } layout.addMember(back); return layout; } /** * Creates a label for the selected range. * * @param dataList * The DataList containing all values for this state. * * @return A label displaying the selected values. */ protected Label getOldRangeSelection(final DataList dataList) { final List<Data> items = dataList.getAll(); final Data dFrom = getData(items, "ld_from"); final Data dTo = getData(items, "ld_to"); final Data dStep = getData(items, "ld_step"); final DataItem[] from = dFrom.getItems(); final DataItem[] to = dTo.getItems(); final DataItem[] step = dStep.getItems(); final StringBuilder sb = new StringBuilder(); sb.append(from[0].getLabel()); sb.append(" " + this.MESSAGES.unitFrom() + " "); sb.append(to[0].getLabel()); sb.append(" " + this.MESSAGES.unitTo() + " "); sb.append(step[0].getLabel()); sb.append(" " + this.MESSAGES.unitWidth()); final Label selected = new Label(sb.toString()); selected.setWidth("130px"); return selected; } /** * Creates a label for the selected locations. * * @param dataList * The DataList containing all values for this state. * * @return A label displaying the selected values. */ protected Label getOldLocationSelection(final DataList dataList) { final List<Data> items = dataList.getAll(); final Data dLocations = getData(items, "ld_locations"); final DataItem[] lItems = dLocations.getItems(); final String[] splitted = StringArrayParseHelper.getArrayFromRawString(lItems[0].getStringValue()); String value = ""; for (final String element : splitted) { try { final NumberFormat nf = NumberFormat.getDecimalFormat(); final double dv = Double.parseDouble(element); value += nf.format(dv) + " "; } catch (final NumberFormatException nfe) { value += element + " "; } } final Label selected = new Label(value); selected.setWidth(130); return selected; } /** * This method reads the default values defined in the DataItems of the Data * objects in <i>list</i>. * * @param list * The DataList container that stores the Data objects. */ protected void initDefaults(final DataList list) { final Data m = getData(list.getAll(), "ld_mode"); final Data l = getData(list.getAll(), "ld_locations"); final Data f = getData(list.getAll(), "ld_from"); final Data t = getData(list.getAll(), "ld_to"); final Data s = getData(list.getAll(), "ld_step"); final DataItem[] fItems = f.getItems(); final DataItem[] tItems = t.getItems(); final DataItem[] sItems = s.getItems(); this.min = Double.valueOf(fItems[0].getStringValue()); this.max = Double.valueOf(tItems[0].getStringValue()); this.step = Double.valueOf(sItems[0].getStringValue()); final DataItem mDef = m.getDefault(); final DataItem lDef = l.getDefault(); final DataItem fDef = f.getDefault(); final DataItem tDef = t.getDefault(); final DataItem sDef = s.getDefault(); final String mDefValue = mDef != null ? mDef.getStringValue() : null; final String theMode = mDefValue != null && mDefValue.length() > 0 ? mDef.getStringValue() : FIELD_VALUE_DISTANCE; this.mode.setValue(FIELD_MODE, theMode); final String fDefValue = fDef != null ? fDef.getStringValue() : null; setFrom(fDefValue != null && fDefValue.length() > 0 ? Double.valueOf(fDef.getStringValue()) : this.min); final String tDefValue = tDef != null ? tDef.getStringValue() : null; setTo(tDefValue != null && tDefValue.length() > 0 ? Double.valueOf(tDef.getStringValue()) : this.max); final String sDefValue = sDef != null ? sDef.getStringValue() : null; setStep(sDefValue != null && sDefValue.length() > 0 ? Double.valueOf(sDef.getStringValue()) : this.step); if (lDef != null) { final String lDefValue = lDef != null ? lDef.getStringValue() : null; if (lDefValue != null && lDefValue.length() > 0) { setLocationValues(lDef.getStringValue()); } } if (theMode.equals(FIELD_VALUE_DISTANCE)) { enableDistanceMode(); this.inputTables.selectTab(1); } else { enableLocationMode(); } this.currentFiltered = (ListGrid) this.inputTables.getSelectedTab().getPane(); this.distancePanel.setValues(getFrom(), getTo(), getStep()); } protected Canvas createWidget(final DataList data) { final VLayout layout = new VLayout(); this.container = new HLayout(); final Canvas checkboxPanel = createRadioButtonPanel(); this.locationPanel = new DoubleArrayPanel(this.MESSAGES.unitLocation(), getLocationValues(), this); this.distancePanel = new DoubleRangePanel(this.MESSAGES.unitFrom(), this.MESSAGES.unitTo(), this.MESSAGES.unitWidth(), 0, 0, 0, /* * initDefaults set the * default values for * this. */ 400, this); this.container.addMember(this.locationPanel); this.container.addMember(this.distancePanel); this.container.hideMember(this.locationPanel); layout.addMember(checkboxPanel); layout.addMember(this.container); this.container.setMembersMargin(30); this.inputTables = new TabSet(); this.inputTables.addTabSelectedHandler(new TabSelectedHandler() { @Override public void onTabSelected(final TabSelectedEvent evt) { LocationDistancePanel.this.filterDescription.clear(); LocationDistancePanel.this.filterRange.clear(); LocationDistancePanel.this.filterResultCount.setValue(""); // The assumption is that location is tab 0 and distance tab 1 final Canvas c = evt.getTabPane(); if (c instanceof ListGrid) { LocationDistancePanel.this.currentFiltered = (ListGrid) c; } } }); final Tab locations = new Tab(this.MESSAGES.locations()); final Tab distances = new Tab(this.MESSAGES.distance()); this.inputTables.setWidth100(); this.inputTables.setHeight100(); locations.setPane(this.locationsTable); distances.setPane(this.distanceTable); this.inputTables.addTab(locations); this.inputTables.addTab(distances); this.filterResultCount = new StaticTextItem(this.MESSAGES.resultCount()); this.filterResultCount.setTitleAlign(Alignment.LEFT); this.filterResultCount.setTitleStyle("color: #000"); this.filterDescription = new TableFilter(); this.filterDescription.setHeight("30px"); this.filterDescription.addFilterHandler(this); this.filterRange = new RangeTableFilter(); this.filterRange.setHeight("30px"); this.filterRange.addFilterHandler(this); this.filterRange.setVisible(false); this.filterCriteria = new SelectItem(); this.filterCriteria.setShowTitle(false); this.filterCriteria.setWidth(100); this.filterCriteria.addChangedHandler(new ChangedHandler() { @Override public void onChanged(final ChangedEvent e) { if (e.getValue().toString().equals("range")) { LocationDistancePanel.this.filterRange.setVisible(true); LocationDistancePanel.this.filterDescription.setVisible(false); LocationDistancePanel.this.filterDescription.clear(); LocationDistancePanel.this.filterResultCount.setValue(""); } else { LocationDistancePanel.this.filterRange.setVisible(false); LocationDistancePanel.this.filterRange.clear(); LocationDistancePanel.this.filterDescription.setVisible(true); LocationDistancePanel.this.filterResultCount.setValue(""); } } }); final LinkedHashMap<String, String> filterMap = new LinkedHashMap<String, String>(); filterMap.put("description", this.MESSAGES.description()); filterMap.put("range", this.MESSAGES.range()); this.filterCriteria.setValueMap(filterMap); this.filterCriteria.setValue("description"); final DynamicForm form = new DynamicForm(); form.setFields(this.filterCriteria); this.inputTables.setHeight("*"); final DynamicForm form2 = new DynamicForm(); form2.setFields(this.filterResultCount); final VLayout helper = new VLayout(); final HLayout filterLayout = new HLayout(); filterLayout.addMember(form); filterLayout.addMember(this.filterDescription); filterLayout.addMember(this.filterRange); filterLayout.setHeight("30px"); helper.addMember(this.inputTables); helper.addMember(filterLayout); helper.addMember(form2); helper.setHeight100(); helper.setWidth100(); this.helperContainer.addMember(helper); filterLayout.setWidth("200"); return layout; } @Override public void onFilterCriteriaChanged(final StringFilterEvent event) { final String search = event.getFilter(); if (search != null && search.length() > 0) { final Criteria c = new Criteria("description", search); this.locationsTable.filterData(c); this.distanceTable.filterData(c); this.filterResultCount.setValue(this.currentFiltered.getRecords().length); } else { this.locationsTable.clearCriteria(); this.distanceTable.clearCriteria(); this.filterResultCount.setValue(""); } } @Override public void onFilterCriteriaChanged(final RangeFilterEvent event) { final Float from = event.getFrom() - 0.001f; final Float to = event.getTo() + 0.001f; GWT.log("filtering range: " + from + " to " + to); Criterion combinedFilter = null; Criterion locationFilter = null; if (from.equals(Float.NaN) && to.equals(Float.NaN)) { this.locationsTable.clearCriteria(); this.distanceTable.clearCriteria(); this.filterResultCount.setValue(""); return; } else if (from.equals(Float.NaN)) { combinedFilter = new Criterion("to", OperatorId.LESS_OR_EQUAL, to); locationFilter = new Criterion("from", OperatorId.LESS_OR_EQUAL, to); this.locationsTable.filterData(locationFilter); this.distanceTable.filterData(combinedFilter); this.filterResultCount.setValue(this.currentFiltered.getRecords().length); return; } else if (to.equals(Float.NaN)) { combinedFilter = new Criterion("from", OperatorId.GREATER_OR_EQUAL, from); this.locationsTable.filterData(combinedFilter); this.distanceTable.filterData(combinedFilter); } else { final AdvancedCriteria c1 = new AdvancedCriteria(OperatorId.AND, new Criterion[] { new Criterion("from", OperatorId.GREATER_OR_EQUAL, from), new Criterion("from", OperatorId.LESS_OR_EQUAL, to) }); final AdvancedCriteria c2 = new AdvancedCriteria(OperatorId.AND, new Criterion[] { new Criterion("to", OperatorId.GREATER_OR_EQUAL, from), new Criterion("to", OperatorId.LESS_OR_EQUAL, to) }); final AdvancedCriteria c3 = new AdvancedCriteria(OperatorId.AND, new Criterion[] { new Criterion("from", OperatorId.LESS_OR_EQUAL, to), new Criterion("to", OperatorId.GREATER_OR_EQUAL, from) }); combinedFilter = new AdvancedCriteria(OperatorId.OR, new Criterion[] { c1, c2, c3 }); } this.locationsTable.filterData(combinedFilter); this.distanceTable.filterData(combinedFilter); this.filterResultCount.setValue(this.currentFiltered.getRecords().length); } @Override public List<String> validate() { if (isLocationMode()) { return validateLocations(); } else { return validateRange(); } } protected List<String> validateLocations() { final List<String> errors = new ArrayList<String>(); final NumberFormat nf = NumberFormat.getDecimalFormat(); try { saveLocationValues(this.locationPanel); } catch (final Exception e) { errors.add(this.MESSAGES.wrongFormat()); } final double[] values = getLocationValues(); final double[] good = new double[values.length]; int idx = 0; for (final double value : values) { if (value < this.min || value > this.max) { String tmp = this.MESSAGES.error_validate_range(); tmp = tmp.replace("$1", nf.format(value)); tmp = tmp.replace("$2", nf.format(this.min)); tmp = tmp.replace("$3", nf.format(this.max)); errors.add(tmp); } else { good[idx++] = value; } } final double[] justGood = new double[idx]; for (int i = 0; i < justGood.length; i++) { justGood[i] = good[i]; } if (!errors.isEmpty()) { this.locationPanel.setValues(justGood); } return errors; } protected List<String> validateRange() { final List<String> errors = new ArrayList<String>(); final NumberFormat nf = NumberFormat.getDecimalFormat(); try { saveDistanceValues(this.distancePanel); } catch (final Exception e) { errors.add(this.MESSAGES.wrongFormat()); } double from = getFrom(); double to = getTo(); final double step = getStep(); if (from < this.min || from > this.max) { String tmp = this.MESSAGES.error_validate_range(); tmp = tmp.replace("$1", nf.format(from)); tmp = tmp.replace("$2", nf.format(this.min)); tmp = tmp.replace("$3", nf.format(this.max)); errors.add(tmp); from = this.min; } if (to < this.min || to > this.max) { String tmp = this.MESSAGES.error_validate_range(); tmp = tmp.replace("$1", nf.format(to)); tmp = tmp.replace("$2", nf.format(this.min)); tmp = tmp.replace("$3", nf.format(this.max)); errors.add(tmp); to = this.max; } if (!errors.isEmpty()) { this.distancePanel.setValues(from, to, step); } return errors; } /** * This method returns the selected data. * * @return the selected/inserted data. */ @Override public Data[] getData() { final List<Data> data = new ArrayList<Data>(); // If we have entered a value and click right afterwards on the // 'next' button, the BlurEvent is not fired, and the values are not // saved. So, we gonna save those values explicitly. if (isLocationMode()) { final Canvas member = this.container.getMember(0); if (member instanceof DoubleArrayPanel) { final DoubleArrayPanel form = (DoubleArrayPanel) member; saveLocationValues(form); } final Data dLocations = getDataLocations(); final DataItem dFrom = new DefaultDataItem("ld_from", "ld_from", ""); final DataItem dTo = new DefaultDataItem("ld_to", "ld_to", ""); final DataItem dStep = new DefaultDataItem("ld_step", "ld_step", ""); data.add(dLocations); data.add(new DefaultData("ld_from", null, null, new DataItem[] { dFrom })); data.add(new DefaultData("ld_to", null, null, new DataItem[] { dTo })); data.add(new DefaultData("ld_step", null, null, new DataItem[] { dStep })); } else { final Canvas member = this.container.getMember(0); if (member instanceof DoubleRangePanel) { final DoubleRangePanel form = (DoubleRangePanel) member; saveDistanceValues(form); } final Data dFrom = getDataFrom(); final Data dTo = getDataTo(); final Data dStep = getDataStep(); final DataItem loc = new DefaultDataItem("ld_locations", "ld_locations", ""); data.add(dFrom); data.add(dTo); data.add(dStep); data.add(new DefaultData("ld_locations", null, null, new DataItem[] { loc })); } final Data dMode = getDataMode(); if (dMode != null) { data.add(dMode); } return data.toArray(new Data[data.size()]); } /** * Returns the Data object for the 'mode' attribute. * * @return the Data object for the 'mode' attribute. */ protected Data getDataMode() { final String value = this.mode.getValueAsString(FIELD_MODE); final DataItem item = new DefaultDataItem("ld_mode", "ld_mode", value); return new DefaultData("ld_mode", null, null, new DataItem[] { item }); } protected Data getDataLocations() { final double[] locations = getLocationValues(); boolean first = true; if (locations == null) { return null; } final StringBuilder sb = new StringBuilder(); for (final double l : locations) { if (!first) { sb.append(" "); } sb.append(l); first = false; } final DataItem item = new DefaultDataItem("ld_locations", "ld_locations", sb.toString()); return new DefaultData("ld_locations", null, null, new DataItem[] { item }); } /** * Returns the Data object for the 'from' attribute. * * @return the Data object for the 'from' attribute. */ protected Data getDataFrom() { final String value = Double.valueOf(getFrom()).toString(); final DataItem item = new DefaultDataItem("ld_from", "ld_from", value); return new DefaultData("ld_from", null, null, new DataItem[] { item }); } /** * Returns the Data object for the 'to' attribute. * * @return the Data object for the 'to' attribute. */ protected Data getDataTo() { final String value = Double.valueOf(getTo()).toString(); final DataItem item = new DefaultDataItem("ld_to", "ld_to", value); return new DefaultData("ld_to", null, null, new DataItem[] { item }); } /** * Returns the Data object for the 'step' attribute. * * @return the Data object for the 'step' attribute. */ protected Data getDataStep() { final String value = Double.valueOf(getStep()).toString(); final DataItem item = new DefaultDataItem("ld_step", "ld_step", value); return new DefaultData("ld_step", null, null, new DataItem[] { item }); } /** * Determines the current input mode. * * @return true, if 'location' is the current input mode, otherwise false. */ public boolean isLocationMode() { final String inputMode = this.mode.getValueAsString(FIELD_MODE); return inputMode.equals(FIELD_VALUE_LOCATION) ? true : false; } /** * Activates the location panel. */ protected void enableLocationMode() { this.mode.setValue(FIELD_MODE, FIELD_VALUE_LOCATION); this.container.hideMember(this.distancePanel); this.container.showMember(this.locationPanel); setupDistanceInfoTable(this.locationsTable, false, false); setupDistanceInfoTable(this.distanceTable, true, true); this.inputTables.updateTab(0, this.locationsTable); this.inputTables.updateTab(1, this.distanceTable); } /** * Activates the distance panel. */ protected void enableDistanceMode() { this.mode.setValue(FIELD_MODE, FIELD_VALUE_DISTANCE); this.container.hideMember(this.locationPanel); this.container.showMember(this.distancePanel); setupDistanceInfoTable(this.locationsTable, true, false); setupDistanceInfoTable(this.distanceTable, false, true); this.inputTables.updateTab(0, this.locationsTable); this.inputTables.updateTab(1, this.distanceTable); } /** * This method switches the input mode between location and distance input. * * @param event * The click event fired by a RadioButtonGroupItem. */ @Override public void onChange(final ChangeEvent event) { final String value = (String) event.getValue(); if (value == null) { return; } if (value.equals(FIELD_VALUE_LOCATION)) { enableLocationMode(); this.filterDescription.clear(); this.filterRange.clear(); this.filterResultCount.setValue(""); // Bring this tab to front. this.inputTables.selectTab(0); } else { enableDistanceMode(); this.filterDescription.clear(); this.filterRange.clear(); this.filterResultCount.setValue(""); // Bring the distanceTable tab to front. this.inputTables.selectTab(1); } } /** * 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. */ @Override public void onBlur(final BlurEvent event) { final FormItem item = event.getItem(); final String field = item.getFieldName(); if (field == null) { return; } if (field.equals(DoubleArrayPanel.FIELD_NAME)) { final DoubleArrayPanel p = (DoubleArrayPanel) event.getForm(); saveLocationValue(p, item); } else { final DoubleRangePanel p = (DoubleRangePanel) event.getForm(); saveDistanceValue(p, item); } } /** * Validates and stores all values entered in the location mode. * * @param p * The DoubleArrayPanel. */ protected void saveLocationValues(final DoubleArrayPanel p) { final FormItem[] formItems = p.getFields(); for (final FormItem item : formItems) { if (item.getFieldName().equals(DoubleArrayPanel.FIELD_NAME)) { saveLocationValue(p, item); } } } /** * Validates and stores all values entered in the distance mode. * * @param p * The DoubleRangePanel. */ protected void saveDistanceValues(final DoubleRangePanel p) { final FormItem[] formItems = p.getFields(); for (final FormItem item : formItems) { saveDistanceValue(p, item); } } /** * Validates and stores a value entered in the location mode. * * @param p * The DoubleArrayPanel. * @param item * The item that needs to be validated. */ protected void saveLocationValue(final DoubleArrayPanel p, final FormItem item) { if (p.validateForm(item)) { setLocationValues(p.getInputValues(item)); } } /** * Validates and stores value entered in the distance mode. * * @param p * The DoubleRangePanel. * @param item * The item that needs to be validated. */ protected void saveDistanceValue(final DoubleRangePanel p, final FormItem item) { if (p.validateForm(item)) { setFrom(p.getFrom()); setTo(p.getTo()); setStep(p.getStep()); } } /** * 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() { this.mode = new DynamicForm(); final RadioGroupItem radio = new RadioGroupItem(FIELD_MODE); radio.setShowTitle(false); radio.setVertical(false); radio.setWrap(false); final LinkedHashMap<String, String> values = new LinkedHashMap<String, String>(); values.put(FIELD_VALUE_LOCATION, this.MESSAGES.location()); values.put(FIELD_VALUE_DISTANCE, this.MESSAGES.distance()); final LinkedHashMap<String, String> initial = new LinkedHashMap<String, String>(); initial.put(FIELD_MODE, FIELD_VALUE_DISTANCE); radio.setValueMap(values); radio.addChangeHandler(this); this.mode.setFields(radio); this.mode.setValues(initial); return this.mode; } protected void createDistanceInputPanel() { final Config config = Config.getInstance(); final String url = config.getServerUrl(); String river = ""; final ArtifactDescription adescr = this.artifact.getArtifactDescription(); final DataList[] data = adescr.getOldData(); if (data != null && data.length > 0) { for (final DataList dl : data) { if (dl.getState().endsWith("river")) { for (int j = 0; j < dl.size(); j++) { final Data d = dl.get(j); final DataItem[] di = d.getItems(); if (di != null && di.length == 1) { river = d.getItems()[0].getStringValue(); } } } } } this.distanceTable.setDataSource(new DistanceInfoDataSource(url, river, "distances")); this.locationsTable.setDataSource(new DistanceInfoDataSource(url, river, "locations")); } protected double getFrom() { return this.from; } protected void setTo(final String to) { try { final double toValue = Double.parseDouble(to); setTo(toValue); } catch (final NumberFormatException nfe) { // Is there anything to do? } } protected void setFrom(final String from) { try { final double fromValue = Double.parseDouble(from); setFrom(fromValue); } catch (final NumberFormatException nfe) { // Is there anything to do? } } protected void setFrom(final double from) { this.from = from; /* The doubling should be removed and this.from abolished */ this.distancePanel.setFrom(from); } protected double getTo() { return this.to; } protected void setTo(final double to) { this.to = to; /* The doubling should be removed and this.to abolished */ this.distancePanel.setTo(to); } protected double getStep() { return this.step; } protected void setStep(final double step) { this.step = step; } protected double[] getLocationValues() { return this.values; } protected void appendLocation(final String loc) { double[] selected; if (getLocationValues() != null) { final double[] val = getLocationValues(); selected = new double[val.length + 1]; for (int i = 0; i < val.length; i++) { selected[i] = val[i]; } try { selected[val.length] = Double.parseDouble(loc); } catch (final NumberFormatException nfe) { // Is there anything to do here? } } else { selected = new double[1]; selected[0] = Double.parseDouble(loc); } setLocationValues(selected); } protected void setLocationValues(final double[] values) { this.values = values; this.locationPanel.setValues(values); } protected void setLocationValues(final String values) { final String[] vs = StringArrayParseHelper.getArrayFromRawString(values); if (vs == null) { return; } final double[] ds = new double[vs.length]; int idx = 0; for (final String s : vs) { try { ds[idx++] = Double.valueOf(s); } catch (final NumberFormatException nfe) { // do nothing } } setLocationValues(ds); } protected void setDistanceValues(final double from, final double to) { setFrom(from); setTo(to); this.distancePanel.setValues(from, to, getStep()); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :