comparison gwt-client/src/main/java/org/dive4elements/river/client/client/ui/uinfo/AbstractVegZonesTablePanel.java @ 9260:b570b6fcc052

VegetationZone color added and disabled
author gernotbelger
date Tue, 17 Jul 2018 10:59:27 +0200
parents af73fdd96920
children 4a6cc7c6716a
comparison
equal deleted inserted replaced
9259:66b003701546 9260:b570b6fcc052
12 import java.util.ArrayList; 12 import java.util.ArrayList;
13 import java.util.List; 13 import java.util.List;
14 14
15 import org.dive4elements.river.client.client.ui.AbstractUIProvider; 15 import org.dive4elements.river.client.client.ui.AbstractUIProvider;
16 import org.dive4elements.river.client.client.ui.PanelHelper; 16 import org.dive4elements.river.client.client.ui.PanelHelper;
17 import org.dive4elements.river.client.client.ui.VegZonePanelHelper;
17 import org.dive4elements.river.client.shared.model.Data; 18 import org.dive4elements.river.client.shared.model.Data;
18 import org.dive4elements.river.client.shared.model.DataItem; 19 import org.dive4elements.river.client.shared.model.DataItem;
19 import org.dive4elements.river.client.shared.model.DataList; 20 import org.dive4elements.river.client.shared.model.DataList;
20 import org.dive4elements.river.client.shared.model.DefaultData; 21 import org.dive4elements.river.client.shared.model.DefaultData;
21 import org.dive4elements.river.client.shared.model.DefaultDataItem; 22 import org.dive4elements.river.client.shared.model.DefaultDataItem;
22 import org.dive4elements.river.client.shared.model.VegetationZone; 23 import org.dive4elements.river.client.shared.model.VegetationZone;
23 24
24 import com.google.gwt.core.client.GWT; 25 import com.google.gwt.core.client.GWT;
26 import com.google.gwt.user.client.ui.Label;
25 import com.smartgwt.client.data.Record; 27 import com.smartgwt.client.data.Record;
26 import com.smartgwt.client.types.Alignment; 28 import com.smartgwt.client.types.Alignment;
27 import com.smartgwt.client.types.ListGridFieldType; 29 import com.smartgwt.client.types.ListGridFieldType;
30 import com.smartgwt.client.types.SortDirection;
28 import com.smartgwt.client.widgets.Canvas; 31 import com.smartgwt.client.widgets.Canvas;
29 import com.smartgwt.client.widgets.Label; 32 import com.smartgwt.client.widgets.form.fields.ColorItem;
30 import com.smartgwt.client.widgets.form.validator.IntegerRangeValidator; 33 import com.smartgwt.client.widgets.form.validator.IntegerRangeValidator;
31 import com.smartgwt.client.widgets.grid.ListGrid; 34 import com.smartgwt.client.widgets.grid.ListGrid;
32 import com.smartgwt.client.widgets.grid.ListGridField; 35 import com.smartgwt.client.widgets.grid.ListGridField;
33 import com.smartgwt.client.widgets.grid.ListGridRecord; 36 import com.smartgwt.client.widgets.grid.ListGridRecord;
34 import com.smartgwt.client.widgets.grid.SortNormalizer; 37 import com.smartgwt.client.widgets.grid.SortNormalizer;
38 import com.smartgwt.client.widgets.grid.events.CellSavedEvent;
39 import com.smartgwt.client.widgets.grid.events.CellSavedHandler;
35 import com.smartgwt.client.widgets.grid.events.RecordClickEvent; 40 import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
36 import com.smartgwt.client.widgets.grid.events.RecordClickHandler; 41 import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
37 import com.smartgwt.client.widgets.layout.HLayout; 42 import com.smartgwt.client.widgets.layout.HLayout;
38 import com.smartgwt.client.widgets.layout.Layout; 43 import com.smartgwt.client.widgets.layout.Layout;
39 import com.smartgwt.client.widgets.layout.VLayout; 44 import com.smartgwt.client.widgets.layout.VLayout;
44 */ 49 */
45 public abstract class AbstractVegZonesTablePanel extends AbstractUIProvider { 50 public abstract class AbstractVegZonesTablePanel extends AbstractUIProvider {
46 private static final long serialVersionUID = 1L; 51 private static final long serialVersionUID = 1L;
47 52
48 private static final String datakey = "vegzones"; 53 private static final String datakey = "vegzones";
49 54 final protected List<ListGridRecord> records = new ArrayList<ListGridRecord>();
50 private final ListGrid elements = new ListGrid(); 55 private final Label validationLabel = new Label();
56 private final ListGrid elements = new ListGrid() {
57
58 @Override
59 protected String getCellCSSText(final ListGridRecord record, final int rowNum, final int colNum) {
60 if (record != null) {
61 if (getFieldName(colNum).equals("color")) {
62 final String color = record.getAttribute("color");
63 return "background-color:" + color + ";";
64 }
65 }
66 return super.getCellCSSText(record, rowNum, colNum); // is null...
67 }
68
69 @Override
70 protected Canvas getCellHoverComponent(final Record record, final java.lang.Integer rowNum, final java.lang.Integer colNum) {
71 if (record != null) {
72 if (getFieldName(colNum).equals("color")) {
73 return null;// "background-color:" + color + ";";
74 }
75 }
76 return super.getCellHoverComponent(record, rowNum, colNum); // is null...
77 }
78 };
51 79
52 protected final ListGrid createTable(final Layout root, final DataList data, final String width, final boolean editable) { 80 protected final ListGrid createTable(final Layout root, final DataList data, final String width, final boolean editable) {
53 81
54 final Label title = new Label(data.get(0).getDescription()); 82 final Label title = new Label(data.get(0).getDescription());
55 title.setHeight("35px"); 83 title.setHeight("35px");
57 this.elements.setWidth(width); 85 this.elements.setWidth(width);
58 this.elements.setHeight(300); 86 this.elements.setHeight(300);
59 this.elements.setShowHeaderContextMenu(false); 87 this.elements.setShowHeaderContextMenu(false);
60 this.elements.setCanReorderFields(false); 88 this.elements.setCanReorderFields(false);
61 this.elements.setCanSort(true); 89 this.elements.setCanSort(true);
62 this.elements.setSortField(1); 90 this.elements.setSortField("to");
63 this.elements.setCanResizeFields(false); 91 this.elements.setCanResizeFields(false);
64 92
65 this.elements.setCanEdit(editable); 93 this.elements.setCanEdit(editable);
94
95 final ListGridField internalNumber = new ListGridField("number", "number"); // valid only if no data is to be added
96 internalNumber.setCanSort(false);
97 internalNumber.setHidden(true);
66 98
67 final ListGridField vegzoneField = new ListGridField("vegzone", this.MSG.uinfo_vegetation_zones_label()); 99 final ListGridField vegzoneField = new ListGridField("vegzone", this.MSG.uinfo_vegetation_zones_label());
68 vegzoneField.setType(ListGridFieldType.TEXT); 100 vegzoneField.setType(ListGridFieldType.TEXT);
69 vegzoneField.setWidth("*"); // 245 101 vegzoneField.setWidth("*"); // 245
70 vegzoneField.setCanSort(false); 102 vegzoneField.setCanSort(false);
71 vegzoneField.setCanDragResize(true); 103 vegzoneField.setCanDragResize(true);
72 104 vegzoneField.setCanEdit(true); // neue Anforderung - doch nicht? ???
73 final ListGridField fromField = createIntTableField("from", this.MSG.uinfo_vegetation_zones_from(), true); 105
74 final ListGridField toField = createIntTableField("to", this.MSG.uinfo_vegetation_zones_to(), false);// nicht sortierbar nach "ÜFDauer bis" 106 final ListGridField fromField = VegZonePanelHelper.createIntTableField("from", this.MSG.uinfo_vegetation_zones_from(), true, getNormalizer(),
107 getValidator());
108 fromField.addCellSavedHandler(new CellSavedHandler() {
109 @Override
110 public void onCellSaved(final CellSavedEvent event) {
111 validateRangeOverlap();
112 }
113 });
114 // war mal ne anforderung, dass sich die Werte anderer Zellen ändern, sodass keine lücken entstehen... mach das jetzt
115 // aber über die Validierung. es sei denn, es soll doch wieder erwünscht sein, dass sihc die werte andere Zellen ändern
116 // fromField.addCellSavedHandler(new CellSavedHandler() {
117 //
118 // @Override
119 // public void onCellSaved(final CellSavedEvent event) {
120 //
121 // final ListGridRecord r = event.getRecord();
122 //
123 // final int from = Integer.valueOf(r.getAttribute("from"));
124 // final int to = Integer.valueOf(r.getAttribute("to"));
125 // final String message = validate(r.getAttribute("from"), r.getAttribute("to"), r.getAttribute("zone"),
126 // r.getAttribute("color"));
127 //
128 // final int key = Integer.valueOf(r.getAttribute("number"));
129 // final int lowerKey = key - 1;
130 // final int higherKey = key + 1;
131 //
132 // final ListGridRecord lower = lowerKey > -1 ? AbstractVegZonesTablePanel.this.records.get(lowerKey) : null;
133 // final ListGridRecord higher = higherKey < AbstractVegZonesTablePanel.this.records.size()
134 // ? AbstractVegZonesTablePanel.this.records.get(higherKey)
135 // : null;
136 //
137 // // primary
138 // if (lower != null) {
139 // lower.setAttribute("to", r.getAttribute("from"));
140 //
141 // // additional:
142 // final int lowerFrom = Integer.valueOf(lower.getAttribute("from"));
143 // if (lowerFrom > from) {
144 // lower.setAttribute("from", from);
145 // }
146 // }
147 //
148 // if (from > to) {
149 // r.setAttribute("to", from);
150 // if (higher != null) {
151 // // higher.setAttribute("from", from); //ist vermutlich too much
152 // final int higherTo = Integer.valueOf(higher.getAttribute("to"));
153 // if (from > higherTo) {
154 // // higher.setAttribute("to", from); //ist vermutlich too much
155 // }
156 // }
157 // }
158 // }
159 // });
160
161 final ListGridField toField = VegZonePanelHelper.createIntTableField("to", this.MSG.uinfo_vegetation_zones_to(), false, getNormalizer(),
162 getValidator());
163 toField.addCellSavedHandler(new CellSavedHandler() {
164 @Override
165 public void onCellSaved(final CellSavedEvent event) {
166 validateRangeOverlap();
167 }
168 });
169 // nicht
170 // sortierbar nach
171 // "ÜFDauer bis"
172 toField.setCanEdit(true);// neue Anforderung - doch nicht?
173
174 final ListGridField colorField = new ListGridField("color", this.MSG.uinfo_vegetation_zone_color());
175 colorField.setHidden(VegetationZone.HAS_COLORS_EDITABLE ? false : true);
176 final ColorItem item = new ColorItem();
177 colorField.setEditorProperties(item);
178
179 colorField.setWidth(80); // 25 too small
180 colorField.setAlign(Alignment.LEFT);
181 colorField.setCanSort(false);
182 colorField.setCanDragResize(false);
183
184 // sortierbar nach
185 // "ÜFDauer bis"
186 toField.setCanEdit(true);// neue Anforderung
75 187
76 if (editable) { 188 if (editable) {
77 final ListGridField removeField = createRemoveField(); 189 final ListGridField removeField = PanelHelper.createRemoveField(this.elements, GWT.getHostPageBaseURL() + this.MSG.removeFeature());
78 this.elements.setFields(vegzoneField, fromField, toField, removeField); 190 this.elements.addRecordClickHandler(new RecordClickHandler() { // adding another custom record-Remove-Handler which is not included in the
191 // Panelhelper TODO: MERGE WITH SupraRegionalPanel!!
192 @Override
193 public void onRecordClick(final RecordClickEvent event) {
194 if (event.getField().getName().equals(removeField.getName())) {
195 validateRangeOverlap();
196 }
197 }
198 });
199 this.elements.setFields(vegzoneField, fromField, toField, colorField, removeField);
79 } else { 200 } else {
80 this.elements.setFields(vegzoneField, fromField, toField); 201 this.elements.setFields(internalNumber, vegzoneField, fromField, toField, colorField);
81 } 202 }
82 203
204 this.elements.sort("from", SortDirection.ASCENDING);
205 this.validationLabel.setHeight("10px");
206 this.validationLabel.getElement().getStyle().setColor("red");
83 addDataInit(data); 207 addDataInit(data);
84 root.setWidth(width); 208 root.setWidth(width);
85 root.addMember(title); 209 root.addMember(title);
86 root.addMember(this.elements); 210 root.addMember(this.elements);
87 root.addMember(PanelHelper.getSpacer(10)); 211 root.addMember(PanelHelper.getSpacer(3));
88 212
213 root.addMember(this.validationLabel);
214 root.addMember(PanelHelper.getSpacer(3));
89 return this.elements; 215 return this.elements;
90 } 216 }
91 217
92 private IntegerRangeValidator getValidator() { 218 private IntegerRangeValidator getValidator() {
93 final IntegerRangeValidator validator = new IntegerRangeValidator(); 219 final IntegerRangeValidator validator = new IntegerRangeValidator();
108 } 234 }
109 }; 235 };
110 return normalizer; 236 return normalizer;
111 } 237 }
112 238
113 private ListGridField createIntTableField(final String key, final String msg, final boolean canSort) {
114 final ListGridField intField = new ListGridField(key, msg);
115 intField.setType(ListGridFieldType.INTEGER);
116 intField.setValidators(getValidator());
117 intField.setWidth(90);
118 intField.setAlign(Alignment.RIGHT);
119 intField.setSortNormalizer(getNormalizer());
120 intField.setCanSort(canSort);
121 intField.setCanDragResize(false);
122
123 return intField;
124 }
125
126 private ListGridField createRemoveField() {
127
128 final ListGridField removeField = new ListGridField("_removeRecord", "Remove Record") {
129 {
130 setType(ListGridFieldType.ICON);
131 setIcon(GWT.getHostPageBaseURL() + AbstractVegZonesTablePanel.this.MSG.removeFeature());
132 setCanEdit(false);
133 setCanFilter(false);
134 setCanSort(false);
135 setCanGroupBy(false);
136 setCanFreeze(false);
137 setWidth(25);
138 setCanDragResize(false);
139 super.setCanToggle(false);
140 }
141 };
142
143 this.elements.addRecordClickHandler(new RecordClickHandler() {
144 @Override
145 public void onRecordClick(final RecordClickEvent event) {
146 // Just handle remove-clicks
147 if (!event.getField().getName().equals(removeField.getName())) {
148 return;
149 }
150 event.getViewer().removeData(event.getRecord());
151 }
152 });
153
154 return removeField;
155 }
156
157 public abstract void createWidget(final Layout root, final DataList data); 239 public abstract void createWidget(final Layout root, final DataList data);
158 240
159 private final void addDataInit(final DataList data) { 241 private final void addDataInit(final DataList data) {
160 for (final Data dataItemContainer : data.getAll()) { 242 for (final Data dataItemContainer : data.getAll()) {
161 if (dataItemContainer.getItems() != null) { 243 if (dataItemContainer.getItems() != null) {
186 root.setWidth(450); 268 root.setWidth(450);
187 createWidget(root, data); 269 createWidget(root, data);
188 270
189 layout.addMember(root); 271 layout.addMember(root);
190 layout.addMember(submit); 272 layout.addMember(submit);
273
274 validateRangeOverlap();// init Text
191 275
192 return layout; 276 return layout;
193 } 277 }
194 278
195 @Override 279 @Override
198 layout.setWidth("400px"); 282 layout.setWidth("400px");
199 final VLayout vLayout = new VLayout(); 283 final VLayout vLayout = new VLayout();
200 vLayout.setWidth(130); 284 vLayout.setWidth(130);
201 final Label label = new Label(dataList.getLabel()); 285 final Label label = new Label(dataList.getLabel());
202 label.setWidth("200px"); 286 label.setWidth("200px");
203 label.setHeight(25); 287 label.setHeight("25px");
204 288
205 final List<Data> items = dataList.getAll(); 289 final List<Data> items = dataList.getAll();
206 final Data str = getData(items, datakey); 290 final Data str = getData(items, datakey);
207 final DataItem[] strItems = str.getItems(); 291 final DataItem[] strItems = str.getItems();
208 292
209 final List<VegetationZone> entries = VegetationZone.parse(strItems[0].getLabel()); 293 final List<VegetationZone> entries = VegetationZone.parse(strItems[0].getLabel());
210 294
211 for (final VegetationZone entry : entries) { 295 for (final VegetationZone entry : entries) {
212 final Label dateLabel = new Label(entry.getZoneName() + " (" + entry.getMin_day_overflow() + "-" + entry.getMax_day_overflow() + ")"); 296 final Label dateLabel = new Label(entry.getZoneName() + " (" + entry.getMin_day_overflow() + "-" + entry.getMax_day_overflow() + ")");
213 dateLabel.setHeight(20); 297 dateLabel.setHeight("20px");
214 vLayout.addMember(dateLabel); 298 vLayout.addMember(dateLabel);
215 } 299 }
216 final Canvas back = getBackButton(dataList.getState()); 300 final Canvas back = getBackButton(dataList.getState());
217 layout.addMember(label); 301 layout.addMember(label);
218 layout.addMember(vLayout); 302 layout.addMember(vLayout);
227 311
228 final ListGridRecord[] lgr = this.elements.getRecords(); 312 final ListGridRecord[] lgr = this.elements.getRecords();
229 if (lgr.length == 0) { 313 if (lgr.length == 0) {
230 return new Data[0]; // TODO: Klären, ob Vegetationszonen-Auswahl Pflicht ist, ob es ein Fallback geben soll usw. 314 return new Data[0]; // TODO: Klären, ob Vegetationszonen-Auswahl Pflicht ist, ob es ein Fallback geben soll usw.
231 } 315 }
316
317 final DataItem item = new DefaultDataItem(datakey, null, VegetationZone.parseListToDataString(getZones(lgr))); // DATA-key
318 data.add(new DefaultData(datakey, null, null, new DataItem[] { item }));
319 return data.toArray(new Data[data.size()]);
320 }
321
322 protected final List<VegetationZone> getZones(final ListGridRecord[] lgr) {
232 final List<VegetationZone> zoneList = new ArrayList<VegetationZone>(); 323 final List<VegetationZone> zoneList = new ArrayList<VegetationZone>();
233 for (final ListGridRecord element : lgr) { 324 for (final ListGridRecord element : lgr) {
234 final Record r = element; 325 final Record r = element;
235 final VegetationZone zone = VegetationZone.createFromTableEntry(r.getAttribute("vegzone"), r.getAttribute("from"), r.getAttribute("to")); 326 final VegetationZone zone = VegetationZone.createFromTableEntry(r.getAttribute("vegzone"), r.getAttribute("from"), r.getAttribute("to"),
327 r.getAttribute("color"));
236 zoneList.add(zone); 328 zoneList.add(zone);
237 } 329 }
238 330 return zoneList;
239 final DataItem item = new DefaultDataItem(datakey, null, VegetationZone.parseListToDataString(zoneList)); // DATA-key
240 data.add(new DefaultData(datakey, null, null, new DataItem[] { item }));
241 return data.toArray(new Data[data.size()]);
242 } 331 }
243 332
244 public final ListGridRecord createEntry(final VegetationZone row) { 333 public final ListGridRecord createEntry(final VegetationZone row) {
245 334
246 final String vegzone = row.getZoneName(); 335 final String vegzone = row.getZoneName();
247 final Integer from = row.getMin_day_overflow(); 336 final Integer from = row.getMin_day_overflow();
248 final Integer to = row.getMax_day_overflow(); 337 final Integer to = row.getMax_day_overflow();
249 338 final String colorStr = row.getHexColor();
250 if (vegzone == null || from == null || to == null) { 339 if (vegzone == null || from == null || to == null) {
251 return null; 340 return null;
252 } 341 }
253 342
254 final ListGridRecord r = new ListGridRecord(); 343 final ListGridRecord r = new ListGridRecord();
255 r.setAttribute("vegzone", vegzone); 344 r.setAttribute("vegzone", vegzone);
256 r.setAttribute("from", from); 345 r.setAttribute("from", from);
257 r.setAttribute("to", to); 346 r.setAttribute("to", to);
347 r.setAttribute("color", colorStr);
348 r.setAttribute("number", this.records.size());
349 this.records.add(r);
258 return r; 350 return r;
259 351
260 } 352 }
353
354 protected String validate(final String fromInput, final String toInput, final String zoneName, final String hexColor) {
355
356 if (fromInput == null || toInput == null || zoneName == null || hexColor == null || fromInput.trim().isEmpty() || toInput.trim().isEmpty()
357 || zoneName.trim().isEmpty() || hexColor.trim().isEmpty())
358 return this.MSG.uinfo_vegetation_zones_validation_empty();
359
360 try {
361 final Integer from = Integer.valueOf(fromInput);
362 final Integer to = Integer.valueOf(toInput);
363
364 if (from < 0 || from > 365)
365 return this.MSG.uinfo_vegetation_zones_validation_range();
366
367 if (to < 0 || to > 365)
368 return this.MSG.uinfo_vegetation_zones_validation_range();
369
370 if (from > to)
371 return this.MSG.uinfo_vegetation_zones_validation_from_greater_to();
372
373 return null;
374 }
375 catch (final NumberFormatException e) {
376 return this.MSG.error_invalid_integer();
377 }
378 }
379
380 @Override
381 public List<String> validate() {
382 final List<String> errors = new ArrayList<String>();
383
384 if (VegetationZone.zonesAreOverlapping(this.getZones(this.elements.getRecords())))
385 errors.add(this.MSG.uinfo_vegetation_zone_overlap());
386 if (VegetationZone.hasGaps(this.getZones(this.elements.getRecords()), 0, 365))
387 errors.add(this.MSG.uinfo_vegetation_zone_has_gaps());
388 return errors;
389 }
390
391 protected final void validateRangeOverlap() {
392 this.validationLabel.setText(validate().toString().replace("[", "").replace("]", "").replace(",", ""));
393 }
261 } 394 }

http://dive4elements.wald.intevation.org