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 import fr.ifremer.tutti.ui.swing.content.operation.catches.species.EditSpeciesBatchPanelUI;
26 import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchRowModel;
27 import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchTableModel;
28 import fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit.SpeciesBatchUI;
29 import fr.ifremer.tutti.ui.swing.util.computable.ComputableData;
30 import jaxx.runtime.SwingUtil;
31 import jaxx.runtime.swing.JTables;
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.nuiton.jaxx.application.swing.table.ColumnIdentifier;
35
36 import javax.swing.AbstractCellEditor;
37 import javax.swing.JTable;
38 import javax.swing.UIManager;
39 import javax.swing.border.LineBorder;
40 import javax.swing.table.DefaultTableCellRenderer;
41 import javax.swing.table.TableCellEditor;
42 import javax.swing.table.TableCellRenderer;
43 import java.awt.Color;
44 import java.awt.Component;
45 import java.awt.Font;
46 import java.awt.event.KeyAdapter;
47 import java.awt.event.KeyEvent;
48 import java.awt.event.MouseAdapter;
49 import java.awt.event.MouseEvent;
50 import java.util.ArrayList;
51 import java.util.List;
52 import java.util.Objects;
53 import java.util.stream.Collectors;
54
55
56
57
58
59
60
61 public class SpeciesFrequencyCellComponent extends DefaultTableCellRenderer {
62
63 private static final long serialVersionUID = 1L;
64
65 protected Color computedDataColor;
66
67
68 private static final Log log = LogFactory.getLog(SpeciesFrequencyCellComponent.class);
69
70 private Font defaulfFont;
71
72 private Font selectedFont;
73
74 public SpeciesFrequencyCellComponent(Color computedDataColor) {
75 setHorizontalAlignment(CENTER);
76 setIcon(SwingUtil.createActionIcon("show-frequency"));
77 this.computedDataColor = computedDataColor;
78 }
79
80 public void setComputedOrNotText(ComputableData<Integer> data) {
81 String text;
82
83 if (data != null && data.getData() != null) {
84 text = String.valueOf(data.getData());
85
86 } else if (data != null && data.getComputedData() != null && data.getComputedData() != 0) {
87
88 String blue = Integer.toHexString(computedDataColor.getRGB()).substring(2);
89 text = "<html><em style='color: #" + blue + "'>" + data.getComputedData() + "</em></html>";
90
91 } else {
92 text = " - ";
93 }
94 setText(text);
95 setToolTipText(text);
96 }
97
98 @Override
99 public Component getTableCellRendererComponent(JTable table,
100 Object value,
101 boolean isSelected,
102 boolean hasFocus,
103 int row,
104 int column) {
105
106 if (defaulfFont == null) {
107 defaulfFont = UIManager.getFont("Table.font");
108 selectedFont = defaulfFont.deriveFont(Font.BOLD);
109 }
110
111 Component result = super.getTableCellRendererComponent(table,
112 value,
113 isSelected,
114 hasFocus,
115 row,
116 column);
117 if (isSelected) {
118 result.setFont(selectedFont);
119 } else {
120 result.setFont(defaulfFont);
121 }
122 return result;
123 }
124
125 public static TableCellRenderer newRender(Color computedDataColor) {
126 return new FrequencyCellRenderer(computedDataColor);
127 }
128
129 public static TableCellEditor newEditor(SpeciesBatchUI ui, Color computedDataColor) {
130 return new FrequencyCellEditor(ui, computedDataColor);
131 }
132
133 public static class FrequencyCellEditor extends AbstractCellEditor implements TableCellEditor {
134
135 private static final long serialVersionUID = 1L;
136
137 protected final SpeciesFrequencyCellComponent component;
138
139 protected final SpeciesBatchUI ui;
140
141 protected JTable table;
142
143 protected SpeciesBatchTableModel tableModel;
144
145 protected ColumnIdentifier<SpeciesBatchRowModel> columnIdentifier;
146
147 protected SpeciesBatchRowModel editRow;
148
149 protected Integer rowIndex;
150
151 protected Integer nextEditableRowIndex;
152
153 protected Integer columnIndex;
154
155 protected SpeciesBatchRowModel previousSiblingRow;
156
157 public FrequencyCellEditor(SpeciesBatchUI ui, Color computedDataColor) {
158 this.ui = ui;
159 component = new SpeciesFrequencyCellComponent(computedDataColor);
160 component.setBorder(new LineBorder(Color.BLACK));
161 component.addKeyListener(new KeyAdapter() {
162 @Override
163 public void keyReleased(KeyEvent e) {
164 if (e.getKeyCode() == KeyEvent.VK_ENTER || e.getKeyCode() == KeyEvent.VK_SPACE) {
165 e.consume();
166 startEdit();
167 }
168 }
169 });
170
171 component.addMouseListener(new MouseAdapter() {
172 @Override
173 public void mouseClicked(MouseEvent e) {
174 e.consume();
175 startEdit();
176 }
177 });
178 }
179
180 public SpeciesBatchRowModel getEditRow() {
181 return editRow;
182 }
183
184 public Integer getNextEditableRowIndex() {
185 return nextEditableRowIndex;
186 }
187
188 public SpeciesBatchRowModel getPreviousSiblingRow() {
189 return previousSiblingRow;
190 }
191
192 public void initEditor(JTable table, int row, int column) {
193 tableModel = (SpeciesBatchTableModel) table.getModel();
194 this.table = table;
195 columnIdentifier = SpeciesBatchTableModel.COMPUTED_NUMBER;
196 rowIndex = row;
197 columnIndex = column;
198 editRow = tableModel.getEntry(row);
199 }
200
201 public void startEdit() {
202
203 Objects.requireNonNull(tableModel, "No table model assigned.");
204 Objects.requireNonNull(editRow, "No editRow found.");
205
206
207 nextEditableRowIndex = tableModel.getNextEditableFrequencyRow(rowIndex + 1);
208
209
210 previousSiblingRow = tableModel.getPreviousSibling(editRow);
211
212 if (log.isDebugEnabled()) {
213 log.debug("Will edit frequencies for row: " + rowIndex +
214 ", nextEditableRow: " + nextEditableRowIndex +
215 ", previous siblingRow: " + previousSiblingRow);
216 }
217
218 EditSpeciesBatchPanelUI parent = ui.getParentContainer(EditSpeciesBatchPanelUI.class);
219 parent.getHandler().editSpeciesFrequencies(this);
220 }
221
222 public void save(SpeciesFrequencyUIModel frequencyModel) {
223
224 if (frequencyModel.isValid()) {
225
226
227
228
229 editRow.setWeight(frequencyModel.getTotalWeight());
230
231 if (frequencyModel.isSimpleCountingMode()) {
232
233 editRow.setNumber(frequencyModel.getSimpleCount());
234
235 editRow.setIndividualObservation(new ArrayList<>());
236 editRow.setFrequency(new ArrayList<>());
237
238 } else {
239
240
241 editRow.setNumber(null);
242
243
244
245
246
247 List<IndividualObservationBatchRowModel> individualObservation = new ArrayList<>();
248
249
250
251 individualObservation.addAll(frequencyModel.getIndividualObservationModel().getRows());
252 if (log.isDebugEnabled()) {
253 log.debug("Push back " + individualObservation.size() + " observations to batch " + frequencyModel.getBatch());
254 }
255
256
257
258 editRow.setIndividualObservation(individualObservation);
259
260
261
262
263
264
265
266
267 List<SpeciesFrequencyRowModel> frequency =
268 frequencyModel.getRows()
269 .stream()
270 .filter(row -> row.isValid() && (row.withNumber() || row.withWeight()))
271 .collect(Collectors.toList());
272
273 if (log.isDebugEnabled()) {
274 log.debug("Push back " + frequency.size() + " frequencies to batch " + frequencyModel.getBatch());
275 }
276
277
278 editRow.setFrequency(frequency);
279
280 }
281
282
283 ui.getHandler().updateTotalFromFrequencies(editRow);
284 }
285
286 ui.getHandler().saveRow(editRow);
287
288 }
289
290 public void save(SpeciesFrequencyUIModel frequencyModel, boolean quit) {
291
292 save(frequencyModel);
293
294 if (quit) {
295 int r = rowIndex;
296 int c = columnIndex;
297
298
299 stopCellEditing();
300
301
302 JTables.doSelectCell(table, r, c);
303 table.requestFocus();
304
305 } else {
306
307
308 int nextR = nextEditableRowIndex;
309 int c = columnIndex;
310
311
312 stopCellEditing();
313
314
315 rowIndex = nextR;
316
317
318 editRow = tableModel.getEntry(rowIndex);
319
320
321 JTables.doSelectCell(table, rowIndex, c);
322
323
324 startEdit();
325 }
326 }
327
328 @Override
329 public Component getTableCellEditorComponent(JTable table,
330 Object value,
331 boolean isSelected,
332 int row,
333 int column) {
334
335 initEditor(table, row, column);
336
337 if (log.isDebugEnabled()) {
338 log.debug("Set columnIdentifier (" + column + ") :: " + columnIdentifier.getPropertyName());
339 }
340 ComputableData<Integer> data = (ComputableData<Integer>) value;
341 component.setComputedOrNotText(data);
342
343 return component;
344 }
345
346 @Override
347 public Object getCellEditorValue() {
348
349 Objects.requireNonNull(editRow, "No editRow found in editor.");
350
351 Object result = null;
352 if (columnIdentifier == SpeciesBatchTableModel.COMPUTED_NUMBER) {
353 result = editRow.getComputedOrNotNumber();
354 }
355 if (log.isDebugEnabled()) {
356 log.debug("editor value (" + columnIdentifier + "): " + result);
357 }
358
359 return result;
360 }
361
362 @Override
363 public void cancelCellEditing() {
364 super.cancelCellEditing();
365 rowIndex = null;
366 nextEditableRowIndex = null;
367 columnIndex = null;
368 editRow = null;
369 }
370 }
371
372 public static class FrequencyCellRenderer implements TableCellRenderer {
373
374 protected final SpeciesFrequencyCellComponent component;
375
376 public FrequencyCellRenderer(Color computedDataColor) {
377 component = new SpeciesFrequencyCellComponent(computedDataColor);
378 }
379
380 @Override
381 public Component getTableCellRendererComponent(JTable table,
382 Object value,
383 boolean isSelected,
384 boolean hasFocus,
385 int row,
386 int column) {
387 component.setForeground(Color.BLACK);
388 ComputableData<Integer> data = (ComputableData<Integer>) value;
389 SpeciesFrequencyCellComponent result =
390 (SpeciesFrequencyCellComponent) component.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
391
392 boolean editable = table.isCellEditable(row, column);
393 result.setEnabled(editable);
394 result.setComputedOrNotText(data);
395 return result;
396 }
397 }
398 }