1 package fr.ifremer.tutti.ui.swing.content.operation.catches.species.frequency;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 import fr.ifremer.tutti.persistence.entities.CaracteristicMap;
28 import fr.ifremer.tutti.persistence.entities.TuttiEntities;
29 import fr.ifremer.tutti.persistence.entities.data.Attachment;
30 import fr.ifremer.tutti.persistence.entities.data.CopyIndividualObservationMode;
31 import fr.ifremer.tutti.persistence.entities.data.SampleCategory;
32 import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol;
33 import fr.ifremer.tutti.persistence.entities.referential.Caracteristic;
34 import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue;
35 import fr.ifremer.tutti.persistence.entities.referential.Species;
36 import fr.ifremer.tutti.service.DecoratorService;
37 import fr.ifremer.tutti.service.sampling.SamplingCodePrefix;
38 import fr.ifremer.tutti.type.WeightUnit;
39 import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.SamplingCodeCellEditor;
40 import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.SamplingCodeCellRenderer;
41 import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchRowModel;
42 import fr.ifremer.tutti.ui.swing.util.TuttiUI;
43 import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil;
44 import fr.ifremer.tutti.ui.swing.util.attachment.AttachmentCellEditor;
45 import fr.ifremer.tutti.ui.swing.util.attachment.AttachmentCellRenderer;
46 import fr.ifremer.tutti.ui.swing.util.caracteristics.CaracteristicMapCellComponent;
47 import fr.ifremer.tutti.ui.swing.util.comment.CommentCellEditor;
48 import fr.ifremer.tutti.ui.swing.util.comment.CommentCellRenderer;
49 import jaxx.runtime.SwingUtil;
50 import org.apache.commons.lang3.StringUtils;
51 import org.apache.commons.logging.Log;
52 import org.apache.commons.logging.LogFactory;
53 import org.jdesktop.swingx.JXTable;
54 import org.jdesktop.swingx.autocomplete.ComboBoxCellEditor;
55 import org.jdesktop.swingx.decorator.HighlightPredicate;
56 import org.jdesktop.swingx.decorator.Highlighter;
57 import org.jdesktop.swingx.table.DefaultTableColumnModelExt;
58 import org.jdesktop.swingx.table.TableColumnExt;
59 import org.jdesktop.swingx.table.TableColumnModelExt;
60 import org.nuiton.decorator.Decorator;
61
62 import javax.swing.JComboBox;
63 import java.awt.Color;
64 import java.beans.PropertyChangeListener;
65 import java.io.Closeable;
66 import java.util.ArrayList;
67 import java.util.Collections;
68 import java.util.HashSet;
69 import java.util.Iterator;
70 import java.util.List;
71 import java.util.Map;
72 import java.util.Objects;
73 import java.util.Set;
74 import java.util.function.Function;
75
76 import static org.nuiton.i18n.I18n.t;
77
78
79
80
81
82
83
84
85 public class IndividualObservationBatchTableHandler implements Closeable {
86
87
88 private static final Log log = LogFactory.getLog(IndividualObservationBatchTableHandler.class);
89
90
91
92
93 private final SpeciesFrequencyUIHandler uiHandler;
94
95
96
97 private final JXTable individualObservationTable;
98
99
100
101 private final SpeciesFrequencyUIModel model;
102
103
104
105 private final IndividualObservationBatchUIModel individualObservationsModel;
106
107
108
109 private final SpeciesFrequencyTableModel frequencyTableModel;
110
111
112
113 private final IndividualObservationBatchTableModel individualObservationTableModel;
114
115
116
117 private final Map<String, Caracteristic> maturityCaracteristics;
118
119
120
121 private final Decorator<Species> speciesDecorator;
122 private final Decorator<Caracteristic> caracteristicDecorator;
123 private final Decorator<Caracteristic> caracteristicTipDecorator;
124
125
126
127 private final IndividualObservationToFrequencyEngine individualObservationToFrequencyEngine;
128
129
130
131 private final IndividualObservationToSamplingCacheEngine individualObservationToSamplingCacheEngine;
132
133
134
135 private final PropertyChangeListener individualObservationRowSizeChangedListener;
136
137
138
139 private final PropertyChangeListener individualObservationRowWeightChangedListener;
140
141
142
143 private final PropertyChangeListener individualObservationRowSamplingCodeChangedListener;
144
145
146
147 private final PropertyChangeListener individualObservationRowCaracteristicsChangedListener;
148
149
150
151
152
153
154 protected final CaracteristicMapCellComponent.CaracteristicMapCellEditor otherCaracteristicsEditor;
155
156 public IndividualObservationBatchTableHandler(SpeciesFrequencyUI ui) {
157
158 this.model = ui.getModel();
159 this.individualObservationsModel = ui.getModel().getIndividualObservationModel();
160 this.uiHandler = ui.getHandler();
161
162 this.speciesDecorator = uiHandler.getDecorator(Species.class, DecoratorService.WITH_SURVEY_CODE_NO_NAME);
163 this.caracteristicDecorator = uiHandler.getDecorator(Caracteristic.class, DecoratorService.CARACTERISTIC_PARAMETER_ONLY_WITH_UNIT);
164 this.caracteristicTipDecorator = uiHandler.getDecorator(Caracteristic.class, DecoratorService.CARACTERISTIC_WITH_UNIT);
165
166 this.individualObservationTable = ui.getObsTable();
167 this.frequencyTableModel = uiHandler.getTableModel();
168 this.individualObservationToFrequencyEngine = new IndividualObservationToFrequencyEngine(model);
169 this.individualObservationToSamplingCacheEngine = new IndividualObservationToSamplingCacheEngine(model);
170
171 List<Caracteristic> maturityCaracteristics = new ArrayList<>(uiHandler.getDataContext().getMaturityCaracteristics());
172
173 this.maturityCaracteristics = TuttiEntities.splitById(maturityCaracteristics);
174
175
176 this.individualObservationRowSizeChangedListener = event -> {
177
178 IndividualObservationBatchRowModel source = (IndividualObservationBatchRowModel) event.getSource();
179 Float oldSize = (Float) event.getOldValue();
180
181 Float weight = source.getWeight();
182
183 CaracteristicQualitativeValue maturity = individualObservationsModel.getMaturityValue(source);
184 CaracteristicQualitativeValue gender = individualObservationsModel.getGender(source);
185
186 String samplingCode = source.getSamplingCode();
187
188 boolean oldValid = source.computeValid(oldSize != null, weight != null);
189 boolean newValid = source.computeValid();
190
191 IndividualObservationBatchRowState oldState = new IndividualObservationBatchRowState(oldSize, weight, maturity, gender, samplingCode, oldValid);
192 IndividualObservationBatchRowState newState = new IndividualObservationBatchRowState(source.getSize(), weight, maturity, gender, samplingCode, newValid);
193 onSamplingRowChanged(source, oldState, newState);
194 onRowChangedForFrequencies(source, oldState, newState);
195
196 individualObservationsModel.recomputeRowValidState(source);
197 model.recomputeCanEditLengthStep();
198 model.setModify(true);
199
200 };
201
202
203 this.individualObservationRowWeightChangedListener = event -> {
204
205 IndividualObservationBatchRowModel source = (IndividualObservationBatchRowModel) event.getSource();
206 if (source.withSize()) {
207
208 Float oldWeight = (Float) event.getOldValue();
209 Float size = source.getSize();
210
211 CaracteristicQualitativeValue maturity = individualObservationsModel.getMaturityValue(source);
212 CaracteristicQualitativeValue gender = individualObservationsModel.getGender(source);
213
214 String samplingCode = source.getSamplingCode();
215
216 boolean oldValid = source.computeValid(size != null, oldWeight != null);
217 boolean newValid = source.computeValid();
218
219 IndividualObservationBatchRowState oldState = new IndividualObservationBatchRowState(size, oldWeight, maturity, gender, samplingCode, oldValid);
220 IndividualObservationBatchRowState newState = new IndividualObservationBatchRowState(size, source.getWeight(), maturity, gender, samplingCode, newValid);
221 onSamplingRowChanged(source, oldState, newState);
222 onRowChangedForFrequencies(source, oldState, newState);
223
224 } else {
225
226 individualObservationsModel.recomputeRowValidState(source);
227
228 }
229
230 model.recomputeCanEditLengthStep();
231 model.setModify(true);
232
233 };
234
235
236 this.individualObservationRowSamplingCodeChangedListener = event -> {
237
238 IndividualObservationBatchRowModel source = (IndividualObservationBatchRowModel) event.getSource();
239 if (source.withSize()) {
240
241 String oldSamplingCode = (String) event.getOldValue();
242
243 Float size = source.getSize();
244 Float weight = source.getWeight();
245 CaracteristicQualitativeValue maturity = individualObservationsModel.getMaturityValue(source);
246 CaracteristicQualitativeValue gender = individualObservationsModel.getGender(source);
247
248 boolean validState = source.computeValid();
249
250 IndividualObservationBatchRowState oldState = new IndividualObservationBatchRowState(size, weight, maturity, gender, oldSamplingCode, validState);
251 IndividualObservationBatchRowState newState = new IndividualObservationBatchRowState(size, weight, maturity, gender, source.getSamplingCode(), validState);
252 onSamplingRowChanged(source, oldState, newState);
253
254 } else {
255
256 individualObservationsModel.recomputeRowValidState(source);
257
258 }
259
260 model.setModify(true);
261
262 };
263
264
265 this.individualObservationRowCaracteristicsChangedListener = event -> {
266
267 IndividualObservationBatchRowModel source = (IndividualObservationBatchRowModel) event.getSource();
268 if (source.withSize()) {
269
270 CaracteristicMap oldCaracteristicMap = (CaracteristicMap) event.getOldValue();
271
272 CaracteristicQualitativeValue oldGender = individualObservationsModel.getGender(oldCaracteristicMap);
273 CaracteristicQualitativeValue newGender = individualObservationsModel.getGender(source);
274
275 if (!Objects.equals(oldGender, newGender)) {
276
277
278
279 Float size = source.getSize();
280 Float weight = source.getWeight();
281 CaracteristicQualitativeValue maturity = individualObservationsModel.getMaturityValue(source);
282 String samplingCode = source.getSamplingCode();
283
284 boolean validState = source.computeValid();
285
286 IndividualObservationBatchRowState oldState = new IndividualObservationBatchRowState(size, weight, maturity, oldGender, samplingCode, validState);
287 IndividualObservationBatchRowState newState = new IndividualObservationBatchRowState(size, weight, maturity, newGender, samplingCode, validState);
288 onSamplingRowChanged(source, oldState, newState);
289
290 } else if (individualObservationsModel.withMaturityCaracteristic()) {
291
292 CaracteristicQualitativeValue oldMaturity = individualObservationsModel.getMaturityValue(oldCaracteristicMap);
293 CaracteristicQualitativeValue newMaturity = individualObservationsModel.getMaturityValue(source);
294
295 if (!Objects.equals(oldMaturity, newMaturity)) {
296
297
298
299 Float size = source.getSize();
300 Float weight = source.getWeight();
301 CaracteristicQualitativeValue gender = individualObservationsModel.getGender(source);
302 String samplingCode = source.getSamplingCode();
303
304 boolean validState = source.computeValid();
305
306 IndividualObservationBatchRowState oldState = new IndividualObservationBatchRowState(size, weight, oldMaturity, gender, samplingCode, validState);
307 IndividualObservationBatchRowState newState = new IndividualObservationBatchRowState(size, weight, newMaturity, gender, samplingCode, validState);
308 onSamplingRowChanged(source, oldState, newState);
309
310 }
311
312 }
313
314 } else {
315
316 individualObservationsModel.recomputeRowValidState(source);
317
318 }
319
320 model.setModify(true);
321
322 };
323
324
325 individualObservationTable.setColumnControlVisible(true);
326
327
328 DefaultTableColumnModelExt columnModel = new DefaultTableColumnModelExt();
329
330 {
331
332
333 uiHandler.addIntegerColumnToModel(columnModel,
334 IndividualObservationBatchTableModel.RANK,
335 TuttiUI.INT_10_DIGITS_PATTERN,
336 individualObservationTable);
337
338 }
339
340 {
341
342 uiHandler.addFloatColumnToModel(columnModel,
343 IndividualObservationBatchTableModel.SIZE,
344 TuttiUI.DECIMAL3_PATTERN,
345 individualObservationTable);
346 }
347
348 WeightUnit individualObservationWeightUnit = uiHandler.getConfig().getIndividualObservationWeightUnit();
349
350 {
351
352 uiHandler.addFloatColumnToModel(columnModel,
353 IndividualObservationBatchTableModel.WEIGHT,
354 individualObservationWeightUnit,
355 individualObservationTable);
356 }
357
358 Caracteristic sexCaracteristic = individualObservationsModel.getSexCaracteristic();
359
360 {
361
362 uiHandler.addCaracteristicColumnToModel(individualObservationTable,
363 columnModel,
364 sexCaracteristic);
365 }
366
367 List<Caracteristic> defaultCaracteristic = new ArrayList<>(individualObservationsModel.getProtocolIndividualObservationCaracteristics());
368
369 defaultCaracteristic.remove(sexCaracteristic);
370
371 for (Caracteristic caracteristic : defaultCaracteristic) {
372 uiHandler.addCaracteristicColumnToModel(individualObservationTable,
373 columnModel,
374 caracteristic);
375 }
376
377
378
379
380 Decorator<CaracteristicQualitativeValue> caracteristicQualitativeDecorator = uiHandler.getDecorator(CaracteristicQualitativeValue.class, null);
381 uiHandler.addComboDataColumnToModel(columnModel,
382 IndividualObservationBatchTableModel.MATURITY,
383 caracteristicQualitativeDecorator,
384 new ArrayList<>());
385
386 {
387
388 otherCaracteristicsEditor = CaracteristicMapCellComponent.newEditor(ui, new HashSet<>());
389 uiHandler.addColumnToModel(columnModel,
390 otherCaracteristicsEditor,
391 CaracteristicMapCellComponent.newRender(uiHandler.getContext()),
392 IndividualObservationBatchTableModel.OTHER_CARACTERISTICS);
393
394 }
395
396 {
397
398
399 uiHandler.addColumnToModel(columnModel,
400 SamplingCodeCellEditor.newEditor(model),
401 SamplingCodeCellRenderer.newRender(),
402 IndividualObservationBatchTableModel.SAMPLING_CODE);
403
404 }
405
406 {
407
408 uiHandler.addColumnToModel(columnModel,
409 CommentCellEditor.newEditor(ui),
410 CommentCellRenderer.newRender(),
411 IndividualObservationBatchTableModel.COMMENT);
412
413 }
414
415 {
416
417 uiHandler.addColumnToModel(columnModel,
418 AttachmentCellEditor.newEditor(ui),
419 AttachmentCellRenderer.newRender(uiHandler.getDecorator(Attachment.class, null)),
420 IndividualObservationBatchTableModel.ATTACHMENT);
421 }
422
423
424
425
426 Function<IndividualObservationBatchRowModel, Void> installListenersOnRow = row -> {
427 row.addPropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_SIZE, individualObservationRowSizeChangedListener);
428 row.addPropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_WEIGHT, individualObservationRowWeightChangedListener);
429 row.addPropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_SAMPLING_CODE, individualObservationRowSamplingCodeChangedListener);
430 row.addPropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_CARACTERISTICS, individualObservationRowCaracteristicsChangedListener);
431 row.addPropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_DEFAULT_CARACTERISTICS, individualObservationRowCaracteristicsChangedListener);
432 return null;
433 };
434
435
436 Function<IndividualObservationBatchRowModel, Void> uninstallListenersOnRow = row -> {
437 row.removePropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_SIZE, individualObservationRowSizeChangedListener);
438 row.removePropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_WEIGHT, individualObservationRowWeightChangedListener);
439 row.removePropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_SAMPLING_CODE, individualObservationRowSamplingCodeChangedListener);
440 row.removePropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_CARACTERISTICS, individualObservationRowCaracteristicsChangedListener);
441 row.removePropertyChangeListener(IndividualObservationBatchRowModel.PROPERTY_DEFAULT_CARACTERISTICS, individualObservationRowCaracteristicsChangedListener);
442 return null;
443 };
444 individualObservationTableModel = new IndividualObservationBatchTableModel(individualObservationWeightUnit,
445 model,
446 columnModel,
447 installListenersOnRow,
448 uninstallListenersOnRow);
449 individualObservationsModel.setIndividualObservationTableModel(individualObservationTableModel);
450
451 individualObservationTable.setModel(individualObservationTableModel);
452 individualObservationTable.setColumnModel(columnModel);
453
454
455 individualObservationTable.getTableHeader().setReorderingAllowed(false);
456
457 uiHandler.addHighlighters(individualObservationTable);
458
459 Color cellWithValueColor = uiHandler.getConfig().getColorCellWithValue();
460
461 Highlighter commentHighlighter = TuttiUIUtil.newBackgroundColorHighlighter(
462 new HighlightPredicate.AndHighlightPredicate(
463 new HighlightPredicate.IdentifierHighlightPredicate(IndividualObservationBatchTableModel.COMMENT),
464
465 (renderer, adapter) -> {
466 String value = (String) adapter.getValue();
467 return StringUtils.isNotBlank(value);
468 }), cellWithValueColor);
469 individualObservationTable.addHighlighter(commentHighlighter);
470
471 uiHandler.installTableKeyListener(columnModel, individualObservationTable, false);
472
473
474 SwingUtil.scrollToTableSelection(individualObservationTable);
475
476 individualObservationsModel.addPropertyChangeListener(IndividualObservationBatchUIModel.PROPERTY_ROWS, evt -> individualObservationTableModel.setRows((List<IndividualObservationBatchRowModel>) evt.getNewValue()));
477
478
479 model.addPropertyChangeListener(SpeciesFrequencyUIModel.PROPERTY_COPY_INDIVIDUAL_OBSERVATION_MODE, evt -> {
480
481 SpeciesFrequencyUIModel source = (SpeciesFrequencyUIModel) evt.getSource();
482 CopyIndividualObservationMode oldCopyMode = (CopyIndividualObservationMode) evt.getOldValue();
483 CopyIndividualObservationMode newCopyMode = (CopyIndividualObservationMode) evt.getNewValue();
484
485 if (newCopyMode == null) {
486
487 return;
488 }
489 boolean nothingCopyMode = CopyIndividualObservationMode.NOTHING == newCopyMode;
490
491 if (!nothingCopyMode) {
492
493 source.setFrequenciesConfigurationMode(FrequencyConfigurationMode.RAFALE);
494 source.setAddIndividualObservationOnRafale(true);
495
496 }
497
498
499 if (source.isInitBatchEdition()) {
500
501 if (log.isInfoEnabled()) {
502 log.info("Skip recompute frequencies from indivudal observations (flag initBatchEdition is on), copyIndividualObservationMode changed from " + oldCopyMode + " to " + newCopyMode);
503 }
504 return;
505 }
506
507 model.clear();
508 model.reloadRows();
509
510
511 individualObservationsModel.setCopyIndividualObservationMode(newCopyMode);
512
513
514 frequencyTableModel.reloadRowsFromIndividualObservations();
515
516 });
517
518 model.addPropertyChangeListener(SpeciesFrequencyUIModel.PROPERTY_LENGTH_STEP_CARACTERISTIC, evt -> {
519
520 Caracteristic newValue = (Caracteristic) evt.getNewValue();
521 individualObservationTableModel.setLengthstepCaracteristic(newValue);
522
523 });
524
525 }
526
527 @Override
528 public void close() {
529
530 model.getIndividualObservationUICache().close();
531 model.getSamplingCodeUICache().close();
532
533 }
534
535 public List<IndividualObservationBatchRowModel> loadRows(Species species, List<IndividualObservationBatchRowModel> individualObservations) {
536
537 individualObservationTableModel.setSpecies(species);
538
539 SamplingCodePrefix samplingCodePrefix = new SamplingCodePrefix(uiHandler.getConfig().getSamplingCodePrefix(), speciesDecorator.toString(species));
540 individualObservationsModel.setSamplingCodePrefix(samplingCodePrefix);
541
542 return individualObservationTableModel.loadRows(individualObservations);
543
544 }
545
546 public void loadSpeciesBatch(SpeciesBatchRowModel speciesBatch, List<IndividualObservationBatchRowModel> individualObservationRows, boolean addToCache) {
547
548 individualObservationsModel.setRows(individualObservationRows);
549
550
551 model.getIndividualObservationUICache().init(speciesBatch.getSpecies(), individualObservationsModel.getRows(), addToCache);
552 model.getSamplingCodeUICache().init(speciesBatch.getSpecies(), individualObservationsModel.getRows(), addToCache);
553
554 individualObservationTable.packAll();
555
556 }
557
558 public boolean isSampleCodeMenusEnabled(int modelRowIndex) {
559 return modelRowIndex >= 0 && individualObservationTable.getSelectedRowCount() == 1
560 && individualObservationTableModel.getRows().get(individualObservationTable.getSelectedRow()).withSamplingCode();
561 }
562
563 public void initMaturityCaracteristic(SpeciesProtocol speciesProtocol) {
564
565 Caracteristic maturityCaracteristic;
566
567 if (speciesProtocol == null) {
568 maturityCaracteristic = null;
569 } else {
570 maturityCaracteristic = maturityCaracteristics.get(speciesProtocol.getMaturityPmfmId());
571 }
572
573
574
575 individualObservationsModel.setMaturityCaracteristic(maturityCaracteristic);
576
577 MaturityColumnIdentifier columnIdentifier = IndividualObservationBatchTableModel.MATURITY;
578 columnIdentifier.setCaracteristic(maturityCaracteristic);
579
580 TableColumnExt columnModel = ((TableColumnModelExt) individualObservationTable.getColumnModel()).getColumnExt(columnIdentifier);
581
582 boolean noMaturity = maturityCaracteristic == null;
583
584 columnModel.setVisible(!noMaturity);
585 ComboBoxCellEditor cellEditor = (ComboBoxCellEditor) columnModel.getCellEditor();
586 JComboBox comboBox = (JComboBox) cellEditor.getComponent();
587
588 List<CaracteristicQualitativeValue> dataList;
589
590 String title;
591 String tip;
592
593 if (noMaturity) {
594 dataList = Collections.emptyList();
595 title = t(columnIdentifier.getHeaderI18nKey());
596 tip = t(columnIdentifier.getHeaderTipI18nKey());
597
598 } else {
599 dataList = new ArrayList<>(maturityCaracteristic.getQualitativeValue());
600 if (!dataList.isEmpty() && dataList.get(0) != null) {
601 dataList.add(0, null);
602 }
603 title = caracteristicDecorator.toString(maturityCaracteristic);
604 tip = caracteristicTipDecorator.toString(maturityCaracteristic);
605 }
606 columnModel.setTitle(title);
607 columnModel.setToolTipText(tip);
608 SwingUtil.fillComboBox(comboBox, dataList, null);
609
610 }
611
612 public void initDefaultCaracteristics(SpeciesBatchRowModel speciesBatch) {
613
614
615 Set<Caracteristic> defaultCaracteristics = new HashSet<>();
616 defaultCaracteristics.addAll(individualObservationsModel.getProtocolIndividualObservationCaracteristics());
617 defaultCaracteristics.add(individualObservationsModel.getSexCaracteristic());
618 if (individualObservationsModel.withMaturityCaracteristic()) {
619 defaultCaracteristics.add(individualObservationsModel.getMaturityCaracteristic());
620 }
621
622 otherCaracteristicsEditor.setCaracteristicsToSkip(defaultCaracteristics);
623
624
625 CaracteristicMap defaultCaracteristicMap = CaracteristicMap.fromCollection(defaultCaracteristics);
626
627
628 CaracteristicMap sampleCategoryValues = new CaracteristicMap();
629 Iterator<SampleCategory<?>> iterator = speciesBatch.iterator();
630 iterator.forEachRemaining(sampleCategory -> {
631 Caracteristic caracteristic = sampleCategory.getCategoryDef().getCaracteristic();
632 defaultCaracteristicMap.replace(caracteristic, sampleCategory.getCategoryValue());
633 sampleCategoryValues.put(caracteristic, sampleCategory.getCategoryValue());
634 });
635
636 individualObservationTableModel.setDefaultCaracteristics(defaultCaracteristicMap);
637 individualObservationsModel.setNotEditableCaracteristic(sampleCategoryValues.keySet());
638
639 }
640
641 private void onSamplingRowChanged(IndividualObservationBatchRowModel row,
642 IndividualObservationBatchRowState oldValue,
643 IndividualObservationBatchRowState newValue) {
644
645 boolean needUpdateSamplingNotificationZone = individualObservationToSamplingCacheEngine.computeSamplingCacheUpdate(oldValue, newValue);
646
647 if (needUpdateSamplingNotificationZone) {
648
649
650 individualObservationsModel.getSamplingNotificationZoneModel().setUpdatedRow(row);
651
652 }
653
654 }
655
656 private void onRowChangedForFrequencies(IndividualObservationBatchRowModel row,
657 IndividualObservationBatchRowState oldValue,
658 IndividualObservationBatchRowState newValue) {
659
660 boolean needRecomputeRowsValidState = individualObservationToFrequencyEngine.computeFrequencyUpdate(model.getCopyIndividualObservationMode(), oldValue, newValue);
661
662 if (needRecomputeRowsValidState) {
663
664
665 individualObservationsModel.recomputeRowValidState(row);
666
667 }
668
669 }
670
671 }
672