1 package fr.ifremer.tutti.ui.swing.content.operation.catches.species.edit;
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 com.google.common.base.Joiner;
26 import com.google.common.collect.Lists;
27 import com.google.common.collect.Sets;
28 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatch;
29 import fr.ifremer.tutti.persistence.entities.data.SpeciesBatchFrequency;
30 import fr.ifremer.tutti.persistence.entities.referential.Species;
31 import fr.ifremer.tutti.service.TuttiDecorator;
32 import jaxx.runtime.SwingUtil;
33 import org.apache.commons.collections4.CollectionUtils;
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.jdesktop.swingx.JXTable;
37 import org.jdesktop.swingx.table.TableColumnExt;
38 import org.nuiton.decorator.DecoratorUtil;
39 import org.nuiton.jaxx.application.swing.table.AbstractApplicationTableModel;
40
41 import javax.swing.ButtonGroup;
42 import javax.swing.JLabel;
43 import javax.swing.JPopupMenu;
44 import javax.swing.JRadioButtonMenuItem;
45 import javax.swing.JSeparator;
46 import javax.swing.SwingUtilities;
47 import javax.swing.table.JTableHeader;
48 import java.awt.Point;
49 import java.awt.event.ActionEvent;
50 import java.awt.event.ActionListener;
51 import java.awt.event.MouseAdapter;
52 import java.awt.event.MouseEvent;
53 import java.io.Serializable;
54 import java.util.Collection;
55 import java.util.Collections;
56 import java.util.List;
57 import java.util.Set;
58
59 import static org.nuiton.i18n.I18n.t;
60
61
62
63
64
65
66
67
68 public class SpeciesBatchRowHelper {
69
70
71 private static final Log log = LogFactory.getLog(SpeciesBatchRowHelper.class);
72
73 public static final String SPECIES_DECORATOR = "decorator";
74
75 public static final String SPECIES_DECORATOR_INDEX = "decoratorIndex";
76
77 public static SpeciesBatchDecoratorComparator<SpeciesBatchRowModel> getSpeciesRowComparator(JXTable table) {
78 TableColumnExt speciesColumn = table.getColumnExt(SpeciesBatchTableModel.SPECIES);
79
80 SpeciesBatchDecoratorComparator<SpeciesBatchRowModel> comparator =
81 (SpeciesBatchDecoratorComparator<SpeciesBatchRowModel>) speciesColumn.getComparator();
82
83 SpeciesBatchDecorator<SpeciesBatchRowModel> decorator = getSpeciesColumnDecorator(table);
84
85 boolean comparatorNull = comparator == null;
86 if (comparatorNull) {
87
88
89 comparator = (SpeciesBatchDecoratorComparator) decorator.getCurrentComparator();
90 }
91
92 if (comparatorNull) {
93
94
95 speciesColumn.setComparator(comparator);
96 }
97 return comparator;
98 }
99
100 protected static SpeciesBatchDecorator<SpeciesBatchRowModel> getSpeciesColumnDecorator(JXTable table) {
101 TableColumnExt speciesColumn = table.getColumnExt(SpeciesBatchTableModel.SPECIES);
102 return (SpeciesBatchDecorator<SpeciesBatchRowModel>) SpeciesBatchRowHelper.getSpeciesColumnDecorator(speciesColumn);
103 }
104
105 public static <E extends SpeciesBatch> int getIndexToInsert(List<E> rows,
106 E newRow,
107 SpeciesSortMode sortMode,
108 SpeciesBatchDecorator decorator) {
109
110 int result;
111
112 int rowsSize = rows.size();
113 if (sortMode == SpeciesSortMode.NONE) {
114
115 result = rowsSize;
116 } else {
117
118
119 Set<Species> speciesSet = Sets.newHashSet();
120 for (E row : rows) {
121 speciesSet.add(row.getSpecies());
122 }
123 Species newSpecies = newRow.getSpecies();
124
125 boolean speciestoAdd = speciesSet.add(newSpecies);
126
127 int nbSpecies = speciesSet.size();
128
129
130 List<Species> speciesList = Lists.newArrayList(speciesSet);
131 TuttiDecorator.TuttiDecoratorComparator<Species> comparator = decorator.getOriginalComparator();
132 comparator.init(decorator, speciesList);
133 Collections.sort(speciesList, comparator);
134 if (sortMode == SpeciesSortMode.DESC) {
135
136
137 Collections.reverse(speciesList);
138 }
139
140 int indexOf = speciesList.indexOf(newSpecies);
141
142 if (!speciestoAdd) {
143
144 indexOf++;
145 }
146
147 if (indexOf == 0) {
148
149
150 result = 0;
151 } else if (indexOf >= nbSpecies) {
152
153
154 result = rowsSize;
155 } else {
156
157
158 Species beforeSpecies;
159 if (speciestoAdd) {
160 beforeSpecies = speciesList.get(indexOf + 1);
161 } else {
162 beforeSpecies = speciesList.get(indexOf);
163 }
164 result = 0;
165 for (E row : rows) {
166 Species species = row.getSpecies();
167 if (beforeSpecies.equals(species)) {
168 break;
169 }
170 result++;
171 }
172 }
173 }
174 return result;
175 }
176
177 public static TuttiDecorator<Species> getSpeciesColumnDecorator(TableColumnExt tableColumn) {
178 return (TuttiDecorator<Species>) tableColumn.getClientProperty(SPECIES_DECORATOR);
179 }
180
181 public static <R extends Serializable, T extends AbstractApplicationTableModel<R>> void installSpeciesColumnComparatorPopup(JXTable table,
182 TableColumnExt speciesColumn,
183 SpeciesSortableRowModel optionalModel,
184 String... tips) {
185
186 ButtonGroup buttonGroup = new ButtonGroup();
187
188 SpeciesDecoratorListener<R, T> speciesDecoratorListener =
189 new SpeciesDecoratorListener<>(table, buttonGroup, speciesColumn, optionalModel);
190
191 TuttiDecorator<Species> decorator =
192 getSpeciesColumnDecorator(speciesColumn);
193
194 JPopupMenu popup = new JPopupMenu();
195 popup.add(new JLabel(t("tutti.ui.change.species.decorator")));
196 popup.add(new JSeparator());
197
198 for (int i = 0, nbContext = decorator.getNbContext(); i < nbContext; i++) {
199 String property = decorator.getProperty(i);
200
201 String i18nName = "tutti.property." + property;
202 speciesColumn.putClientProperty(i18nName, tips[i]);
203 JRadioButtonMenuItem item = new JRadioButtonMenuItem(tips[i]);
204 item.putClientProperty(SPECIES_DECORATOR_INDEX, i);
205 item.addActionListener(speciesDecoratorListener);
206 if (i == 0) {
207
208 item.setSelected(true);
209 }
210 buttonGroup.add(item);
211 popup.add(item);
212 }
213
214
215 speciesDecoratorListener.recomputeSpeciesColumnTip();
216
217
218 table.getTableHeader().addMouseListener(
219 new ShowSpeciesDecoratorPopupListener(popup));
220
221 }
222
223 public static <R extends SpeciesBatch> void sortSpeciesRows(JXTable table,
224 SpeciesBatchDecorator decorator,
225 List<R> rows,
226 SpeciesSortMode speciesSortMode) {
227
228 SpeciesBatchDecoratorComparator comparator = getSpeciesRowComparator(table);
229 comparator.setSpeciesSortMode(speciesSortMode);
230 comparator.init(decorator, rows);
231
232 switch (speciesSortMode) {
233
234 case NONE:
235
236 break;
237 case ASC:
238 case DESC:
239
240 DecoratorUtil.sort(decorator, rows, decorator.getContextIndex());
241 break;
242 }
243 }
244
245
246
247
248
249
250
251
252
253 public static <F extends SpeciesBatchFrequency> Float getFrequenciesTotalWeight(Collection<F> frequency) {
254
255 if (CollectionUtils.isEmpty(frequency)) {
256
257
258 return null;
259
260 }
261
262 float frequencyTotalWeight = 0;
263 for (SpeciesBatchFrequency aFrequency : frequency) {
264
265 if (aFrequency.getWeight() == null) {
266
267
268
269
270 return null;
271 }
272
273 frequencyTotalWeight += aFrequency.getWeight();
274
275 }
276
277 return frequencyTotalWeight;
278
279 }
280
281 protected static class SpeciesDecoratorListener<R extends Serializable, T extends AbstractApplicationTableModel<R>> implements ActionListener {
282
283 protected final JXTable table;
284
285 protected final ButtonGroup buttonGroup;
286
287 protected final SpeciesSortableRowModel optionalModel;
288
289 protected final TuttiDecorator<Species> decorator;
290
291 protected final TableColumnExt column;
292
293 public SpeciesDecoratorListener(JXTable table,
294 ButtonGroup buttonGroup,
295 TableColumnExt speciesColumn,
296 SpeciesSortableRowModel optionalModel) {
297 this.table = table;
298 this.buttonGroup = buttonGroup;
299 this.optionalModel = optionalModel;
300 this.column = speciesColumn;
301 this.decorator = getSpeciesColumnDecorator(column);
302 }
303
304 @Override
305 public void actionPerformed(ActionEvent e) {
306
307 JRadioButtonMenuItem source = (JRadioButtonMenuItem) e.getSource();
308 buttonGroup.setSelected(source.getModel(), true);
309
310 Integer index =
311 (Integer) source.getClientProperty(SPECIES_DECORATOR_INDEX);
312
313 if (log.isInfoEnabled()) {
314 log.info("Selected decorator context index: " + index);
315 }
316
317
318 decorator.setContextIndex(index);
319
320 column.setComparator(decorator.getCurrentComparator());
321
322
323 recomputeSpeciesColumnTip();
324
325 if (optionalModel != null) {
326
327
328 optionalModel.setSpeciesDecoratorContextIndex(index);
329 } else {
330
331
332 T tableModel = (T) table.getModel();
333
334
335 List<R> rowsToReSelect = Lists.newArrayList();
336 for (int rowIndex : SwingUtil.getSelectedModelRows(table)) {
337 R row = tableModel.getEntry(rowIndex);
338 rowsToReSelect.add(row);
339 }
340
341
342 tableModel.fireTableDataChanged();
343
344
345 for (R row : rowsToReSelect) {
346 int modelRowIndex = tableModel.getRowIndex(row);
347 SwingUtil.addRowSelectionInterval(table, modelRowIndex);
348 }
349 }
350 }
351
352 public void recomputeSpeciesColumnTip() {
353 List<String> tips = Lists.newArrayList();
354 for (int i = 0, nbContext = decorator.getNbContext(); i < nbContext; i++) {
355 String property = decorator.getProperty(i);
356
357 String i18nName = "tutti.property." + property;
358 String tip = (String) column.getClientProperty(i18nName);
359 tips.add(tip);
360 }
361 String tip = Joiner.on(" - ").join(tips);
362 column.setToolTipText(tip);
363 }
364 }
365
366 protected static class ShowSpeciesDecoratorPopupListener extends MouseAdapter {
367
368 private final JPopupMenu popup;
369
370 public ShowSpeciesDecoratorPopupListener(JPopupMenu popup) {
371 this.popup = popup;
372 }
373
374 @Override
375 public void mouseClicked(MouseEvent e) {
376 JTableHeader source = (JTableHeader) e.getSource();
377 Point point = e.getPoint();
378 int columnIndex = source.columnAtPoint(point);
379
380 boolean rightClick = SwingUtilities.isRightMouseButton(e);
381 if (columnIndex == 0 && rightClick) {
382 e.consume();
383 popup.show(source, e.getX(), e.getY());
384 }
385 }
386 }
387 }