Revision 19ba9005
Added by Andreas Kohlbecker over 6 years ago
src/main/java/eu/etaxonomy/vaadin/component/ToManyRelatedEntitiesListSelect.java | ||
---|---|---|
47 | 47 |
|
48 | 48 |
private FieldGroup parentFieldGroup = null; |
49 | 49 |
|
50 |
Boolean valueInitiallyWasNull = null; |
|
51 |
|
|
50 | 52 |
protected boolean isOrderedCollection = false; |
51 | 53 |
|
52 | 54 |
private boolean withEditButton = false; |
... | ... | |
59 | 61 |
|
60 | 62 |
private GridLayout grid = new GridLayout(GRID_COLS, 1); |
61 | 63 |
|
64 |
private EntityFieldInstantiator<F> entityFieldInstantiator; |
|
65 |
|
|
62 | 66 |
public ToManyRelatedEntitiesListSelect(Class<V> itemType, Class<F> fieldType, String caption){ |
63 | 67 |
this.fieldType = fieldType; |
64 | 68 |
this.itemType = itemType; |
... | ... | |
86 | 90 |
*/ |
87 | 91 |
private void addRowAfter(F field) { |
88 | 92 |
|
93 |
List<V> nestedValues = getValueFromNestedFields(); |
|
94 |
|
|
95 |
if(isOrderedCollection){ |
|
96 |
|
|
97 |
} else { |
|
98 |
|
|
99 |
} |
|
100 |
|
|
89 | 101 |
Integer row = findRow(field); |
90 | 102 |
|
91 | 103 |
grid.insertRow(row + 1); |
... | ... | |
146 | 158 |
} |
147 | 159 |
|
148 | 160 |
/** |
149 |
* |
|
161 |
* update Value is only called in turn of UI changes like adding, removing, swapping rows
|
|
150 | 162 |
*/ |
151 |
protected void updateValue() {
|
|
163 |
private void updateValue() {
|
|
152 | 164 |
List<V> nestedValues = getValueFromNestedFields(); |
153 | 165 |
List<V> beanList = getValue(); |
154 | 166 |
beanList.clear(); |
155 | 167 |
beanList.addAll(nestedValues); |
156 |
setInternalValue(beanList); |
|
168 |
setInternalValue(beanList, false);
|
|
157 | 169 |
} |
158 | 170 |
|
159 | 171 |
/** |
... | ... | |
207 | 219 |
@Override |
208 | 220 |
protected void setInternalValue(List<V> newValue) { |
209 | 221 |
|
210 |
grid.removeAllComponents(); |
|
211 |
grid.setRows(1); |
|
222 |
setInternalValue(newValue, true); |
|
223 |
|
|
224 |
} |
|
225 |
|
|
226 |
protected void setInternalValue(List<V> newValue, boolean doUpdateFields) { |
|
227 |
|
|
228 |
super.setInternalValue(newValue); |
|
229 |
|
|
230 |
if(valueInitiallyWasNull == null){ |
|
231 |
valueInitiallyWasNull = newValue == null; |
|
232 |
} |
|
212 | 233 |
|
213 | 234 |
if(newValue != null){ |
214 |
super.setInternalValue(newValue); |
|
215 | 235 |
|
216 | 236 |
// newValue is already converted, need to use the original value from the data source |
217 | 237 |
isOrderedCollection = List.class.isAssignableFrom(getPropertyDataSource().getValue().getClass()); |
218 | 238 |
|
219 |
int row = 0; |
|
220 |
if(newValue.size() > 0){ |
|
221 |
for(V val : newValue){ |
|
222 |
row = addNewRow(row, val); |
|
223 |
} |
|
224 |
} |
|
225 | 239 |
} |
226 | 240 |
|
227 |
if(newValue == null || newValue.isEmpty()) { |
|
228 |
// add an empty row |
|
241 |
createFieldsForData(); |
|
242 |
|
|
243 |
} |
|
244 |
|
|
245 |
private void createFieldsForData(){ |
|
246 |
|
|
247 |
grid.removeAllComponents(); |
|
248 |
grid.setRows(1); |
|
249 |
|
|
250 |
List<V> data = getValue(); |
|
251 |
if(data == null || data.isEmpty()){ |
|
229 | 252 |
addNewRow(0, null); |
253 |
} else { |
|
254 |
int row = 0; |
|
255 |
for(V val : data){ |
|
256 |
row = addNewRow(row, val); |
|
257 |
} |
|
230 | 258 |
} |
259 |
|
|
260 |
} |
|
261 |
|
|
262 |
/** |
|
263 |
* Obtains the List of values directly from the nested fields and ignores the |
|
264 |
* value of the <code>propertyDataSource</code>. This is useful when the ToManyRelatedEntitiesListSelect |
|
265 |
* is operating on a transient field, in which case the property is considered being read only by vaadin |
|
266 |
* so that the commit is doing nothing. |
|
267 |
* |
|
268 |
* See also {@link AbstractCdmEditorPresenter#handleTransientProperties(DTO bean)} |
|
269 |
* |
|
270 |
* @return |
|
271 |
*/ |
|
272 |
public List<V> getValueFromNestedFields() { |
|
273 |
List<V> nestedValues = new ArrayList<>(); |
|
274 |
for(F f : getNestedFields()) { |
|
275 |
logger.trace( |
|
276 |
String.format("getValueFromNestedFields() - %s:%s", |
|
277 |
f != null ? f.getClass().getSimpleName() : "null", |
|
278 |
f != null && f.getValue() != null ? f.getValue() : "null" |
|
279 |
)); |
|
280 |
V value = f.getValue(); |
|
281 |
if(f != null /*&& value != null*/){ |
|
282 |
nestedValues.add(f.getValue()); |
|
283 |
} |
|
284 |
} |
|
285 |
return nestedValues; |
|
231 | 286 |
} |
232 | 287 |
|
233 | 288 |
/** |
... | ... | |
238 | 293 |
protected int addNewRow(int row, V val) { |
239 | 294 |
try { |
240 | 295 |
F field = newFieldInstance(val); |
296 |
field.addValueChangeListener(e -> { |
|
297 |
updateValue(); |
|
298 |
}); |
|
241 | 299 |
Property ds = getPropertyDataSource(); |
242 | 300 |
if(ds != null){ |
243 | 301 |
Object parentVal = ds.getValue(); |
... | ... | |
331 | 389 |
|
332 | 390 |
|
333 | 391 |
protected List<F> getNestedFields(){ |
392 |
|
|
334 | 393 |
List<F> nestedFields = new ArrayList<>(grid.getRows()); |
335 | 394 |
for(int r = 0; r < grid.getRows(); r++){ |
336 | 395 |
F f = (F) grid.getComponent(GRID_X_FIELD, r); |
... | ... | |
351 | 410 |
* @throws IllegalAccessException |
352 | 411 |
*/ |
353 | 412 |
protected F newFieldInstance(V val) throws InstantiationException, IllegalAccessException { |
354 |
F field = fieldType.newInstance(); |
|
413 |
|
|
414 |
F field; |
|
415 |
if(entityFieldInstantiator != null){ |
|
416 |
field = entityFieldInstantiator.createNewInstance(); |
|
417 |
} else { |
|
418 |
field = fieldType.newInstance(); |
|
419 |
} |
|
420 |
|
|
355 | 421 |
field.setWidth(100, Unit.PERCENTAGE); |
356 | 422 |
field.setValue(val); |
423 |
|
|
357 | 424 |
// TODO |
358 | 425 |
// when passing null as value the field must take care of creating a new |
359 | 426 |
// instance by overriding setValue() in future we could improve this by passing a |
... | ... | |
415 | 482 |
f.commit(); |
416 | 483 |
|
417 | 484 |
} |
485 |
/* |
|
486 |
List<V> list = (List<V>) getPropertyDataSource().getValue(); |
|
487 |
|
|
488 |
Person p = Person.NewInstance(); |
|
489 |
p.setTitleCache("Hacky", true); |
|
490 |
list.add((V) p); |
|
491 |
|
|
492 |
List<V> clonedList = new ArrayList<>(list); |
|
493 |
list.clear(); |
|
494 |
for(V value : clonedList){ |
|
495 |
if(value != null){ |
|
496 |
list.add(value); |
|
497 |
} |
|
498 |
} |
|
499 |
// |
|
418 | 500 |
// calling super.commit() is useless if operating on a transient property!! |
419 | 501 |
super.commit(); |
420 |
} |
|
421 |
|
|
422 |
/** |
|
423 |
* Obtains the List of values directly from the nested fields and ignores the |
|
424 |
* value of the <code>propertyDataSource</code>. This is useful when the ToManyRelatedEntitiesListSelect |
|
425 |
* is operating on a transient field, in which case the property is considered being read only by vaadin |
|
426 |
* so that the commit is doing nothing. |
|
427 |
* |
|
428 |
* See also {@link AbstractCdmEditorPresenter#handleTransientProperties(DTO bean)} |
|
429 |
* |
|
430 |
* @return |
|
431 |
*/ |
|
432 |
public List<V> getValueFromNestedFields() { |
|
433 |
List<V> nestedValues = new ArrayList<>(); |
|
434 |
for(F f : getNestedFields()) { |
|
435 |
logger.trace( |
|
436 |
String.format("getValueFromNestedFields() - %s:%s", |
|
437 |
f != null ? f.getClass().getSimpleName() : "null", |
|
438 |
f != null && f.getValue() != null ? f.getValue() : "null" |
|
439 |
)); |
|
440 |
V value = f.getValue(); |
|
441 |
if(f != null && value != null){ |
|
442 |
nestedValues.add(f.getValue()); |
|
443 |
} |
|
444 |
} |
|
445 |
return nestedValues; |
|
502 |
if(getValue().isEmpty() && valueInitiallyWasNull){ |
|
503 |
setPropertyDataSource(null); |
|
504 |
} |
|
505 |
*/ |
|
446 | 506 |
} |
447 | 507 |
|
448 | 508 |
/** |
... | ... | |
490 | 550 |
return true; |
491 | 551 |
} |
492 | 552 |
|
553 |
/** |
|
554 |
* @return the enityFieldInstantiator |
|
555 |
*/ |
|
556 |
public EntityFieldInstantiator<F> getEntityFieldInstantiator() { |
|
557 |
return entityFieldInstantiator; |
|
558 |
} |
|
559 |
|
|
560 |
/** |
|
561 |
* @param enityFieldInstantiator the enityFieldInstantiator to set |
|
562 |
*/ |
|
563 |
public void setEntityFieldInstantiator(EntityFieldInstantiator<F> entityFieldInstantiator) { |
|
564 |
this.entityFieldInstantiator = entityFieldInstantiator; |
|
565 |
} |
|
493 | 566 |
|
494 | 567 |
|
495 | 568 |
} |
Also available in: Unified diff
fix #7135 TeamOrPersonField allows selecting from existing Persons and Teams