View Javadoc
1   package fr.ifremer.tutti.ui.swing.util.caracteristics;
2   
3   /*
4    * #%L
5    * Tutti :: UI
6    * %%
7    * Copyright (C) 2012 - 2014 Ifremer
8    * %%
9    * This program is free software: you can redistribute it and/or modify
10   * it under the terms of the GNU General Public License as
11   * published by the Free Software Foundation, either version 3 of the 
12   * License, or (at your option) any later version.
13   * 
14   * This program is distributed in the hope that it will be useful,
15   * but WITHOUT ANY WARRANTY; without even the implied warranty of
16   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   * GNU General Public License for more details.
18   * 
19   * You should have received a copy of the GNU General Public 
20   * License along with this program.  If not, see
21   * <http://www.gnu.org/licenses/gpl-3.0.html>.
22   * #L%
23   */
24  
25  import com.google.common.base.Preconditions;
26  import com.google.common.collect.Sets;
27  import fr.ifremer.tutti.persistence.entities.CaracteristicMap;
28  import fr.ifremer.tutti.persistence.entities.referential.Caracteristic;
29  import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue;
30  import fr.ifremer.tutti.ui.swing.TuttiUIContext;
31  import fr.ifremer.tutti.ui.swing.util.TuttiUI;
32  import fr.ifremer.tutti.ui.swing.util.TuttiUIUtil;
33  import jaxx.runtime.SwingUtil;
34  import org.apache.commons.collections4.MapUtils;
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.nuiton.decorator.Decorator;
38  import org.nuiton.jaxx.application.swing.table.AbstractApplicationTableModel;
39  
40  import javax.swing.AbstractCellEditor;
41  import javax.swing.JTable;
42  import javax.swing.border.LineBorder;
43  import javax.swing.table.DefaultTableCellRenderer;
44  import javax.swing.table.TableCellEditor;
45  import javax.swing.table.TableCellRenderer;
46  import java.awt.Color;
47  import java.awt.Component;
48  import java.awt.Font;
49  import java.awt.event.KeyAdapter;
50  import java.awt.event.KeyEvent;
51  import java.awt.event.MouseAdapter;
52  import java.awt.event.MouseEvent;
53  import java.io.Serializable;
54  import java.util.Collections;
55  import java.util.Objects;
56  import java.util.Set;
57  
58  import static org.nuiton.i18n.I18n.t;
59  
60  /**
61   * @author Kevin Morin - kmorin@codelutin.com
62   * @since 1.4
63   */
64  public class CaracteristicMapCellComponent extends DefaultTableCellRenderer {
65  
66      private static final long serialVersionUID = 1L;
67  
68      /** Logger. */
69      private static final Log log =
70              LogFactory.getLog(CaracteristicMapCellComponent.class);
71  
72      protected Decorator<Caracteristic> caracteristicDecorator;
73  
74      protected Decorator<CaracteristicQualitativeValue> valueDecorator;
75  
76      protected Color computedDataColor;
77  
78      public CaracteristicMapCellComponent(TuttiUIContext context) {
79          super();
80          this.caracteristicDecorator =
81                  context.getDecoratorService().getDecoratorByType(Caracteristic.class);
82          this.valueDecorator =
83                  context.getDecoratorService().getDecoratorByType(CaracteristicQualitativeValue.class);
84          this.computedDataColor = context.getConfig().getColorComputedWeights();
85  
86          setHorizontalAlignment(CENTER);
87          setIcon(SwingUtil.createActionIcon("show-frequency"));
88      }
89  
90      public void setText(CaracteristicMap map) {
91          String s = "-";
92          if (map != null && map.size() > 0) {
93              s = String.valueOf(map.size());
94          }
95          setText(s);
96          Font f = this.getFont();
97          f = f.deriveFont(Font.ITALIC);
98          setFont(f);
99          setForeground(computedDataColor);
100     }
101 
102     public void setToolTipText(CaracteristicMap map) {
103         StringBuilder builder = new StringBuilder();
104         if (map != null) {
105             builder.append("<html><ul>");
106             if (MapUtils.isEmpty(map)) {
107                 builder.append("<li>");
108                 builder.append(t("tutti.caracteristicMapEditor.none.tip"));
109                 builder.append("</li>");
110             }
111             for (Caracteristic caracteristic : map.keySet()) {
112                 builder.append("<li>");
113                 builder.append(caracteristicDecorator.toString(caracteristic));
114                 builder.append(" : ");
115                 Serializable bean = map.get(caracteristic);
116                 if (bean instanceof CaracteristicQualitativeValue) {
117                     builder.append(valueDecorator.toString(bean));
118                 } else {
119                     builder.append(bean);
120                 }
121                 builder.append("</li>");
122             }
123             builder.append("</ul></html>");
124         }
125         setToolTipText(builder.toString());
126     }
127 
128     public static TableCellRenderer newRender(TuttiUIContext context) {
129         return new CaracteristicMapCellRenderer(context);
130     }
131 
132     public static CaracteristicMapCellEditor newEditor(TuttiUI ui, Set<Caracteristic> caracteristicsToSkip) {
133         return new CaracteristicMapCellEditor(ui, caracteristicsToSkip);
134     }
135 
136     public static class CaracteristicMapCellEditor extends AbstractCellEditor implements TableCellEditor {
137 
138         private static final long serialVersionUID = 1L;
139 
140         protected final CaracteristicMapCellComponent component;
141 
142         protected final TuttiUI ui;
143 
144         protected JTable table;
145 
146         protected AbstractApplicationTableModel<CaracteristicMapColumnRowModel> tableModel;
147 
148         protected CaracteristicMapColumnRowModel editRow;
149 
150         protected Set<Caracteristic> caracteristicsUsed;
151 
152         protected Set<Caracteristic> caracteristicsToSkip;
153 
154         protected Integer rowIndex;
155 
156         protected Integer columnIndex;
157 
158         public CaracteristicMapCellEditor(TuttiUI ui,
159                                           Set<Caracteristic> caracteristicsToSkip) {
160             this.ui = ui;
161             this.caracteristicsToSkip = Collections.unmodifiableSet(caracteristicsToSkip);
162             component = new CaracteristicMapCellComponent(ui.getHandler().getContext());
163             component.setBorder(new LineBorder(Color.BLACK));
164             component.addKeyListener(new KeyAdapter() {
165                 @Override
166                 public void keyReleased(KeyEvent e) {
167                     if (e.getKeyCode() == KeyEvent.VK_ENTER ||
168                         e.getKeyCode() == KeyEvent.VK_SPACE) {
169                         e.consume();
170                         startEdit();
171                     }
172                 }
173             });
174 
175             component.addMouseListener(new MouseAdapter() {
176                 @Override
177                 public void mouseClicked(MouseEvent e) {
178                     e.consume();
179                     startEdit();
180                 }
181             });
182         }
183 
184         public void setCaracteristicsToSkip(Set<Caracteristic> caracteristicsToSkip) {
185             Objects.requireNonNull(caracteristicsToSkip);
186             this.caracteristicsToSkip = Collections.unmodifiableSet(caracteristicsToSkip);
187         }
188 
189         protected void startEdit() {
190 
191             Preconditions.checkNotNull(tableModel, "No table model assigned.");
192 
193             // open frequency dialog
194 
195             Preconditions.checkNotNull(editRow, "No editRow found.");
196 
197             if (log.isDebugEnabled()) {
198                 log.debug("Will edit frequencies for row: " + rowIndex);
199             }
200 
201             // get the caracteristics set to the other rows
202             if (caracteristicsUsed == null) {
203                 caracteristicsUsed = Sets.newHashSet();
204                 for (CaracteristicMapColumnRowModel row : tableModel.getRows()) {
205                     CaracteristicMap map = row.getCaracteristics();
206                     if (map != null) {
207                         caracteristicsUsed.addAll(map.keySet());
208                     }
209                 }
210             }
211             caracteristicsUsed.removeAll(caracteristicsToSkip);
212 
213             CaracteristicMapColumnUIHandler handler = (CaracteristicMapColumnUIHandler) ui.getHandler();
214             CaracteristicMapEditorUI caracteristicMapEditor = handler.getCaracteristicMapEditor();
215             // remove all default caracteristics (caracteristicsToSkip)
216             caracteristicMapEditor.getModel().computeAvailableCaracteristics(caracteristicsToSkip);
217             caracteristicMapEditor.getHandler().editBatch(editRow, this, caracteristicsUsed);
218             handler.showCaracteristicMapEditor(editRow);
219         }
220 
221         public void validateEdition(CaracteristicMapEditorUIModel caracteristicMapEditorModel) {
222             CaracteristicMap map = caracteristicMapEditorModel.getCaracteristicMap();
223             component.setText(map);
224             component.setToolTipText(map);
225             editRow.setCaracteristics(map);
226             caracteristicsUsed.addAll(map.keySet());
227 
228             int r = rowIndex;
229             int c = columnIndex;
230 
231             // stop edition
232             stopCellEditing();
233 
234             // reselect this cell
235             TuttiUIUtil.doSelectCell(table, r, c);
236             table.requestFocus();
237         }
238 
239         public void closeEditor() {
240             CaracteristicMapColumnUIHandler handler = (CaracteristicMapColumnUIHandler) ui.getHandler();
241             handler.hideCaracteristicMapEditor();
242         }
243 
244         @Override
245         public Component getTableCellEditorComponent(JTable table,
246                                                      Object value,
247                                                      boolean isSelected,
248                                                      int row,
249                                                      int column) {
250             tableModel = (AbstractApplicationTableModel) table.getModel();
251             this.table = table;
252 
253             rowIndex = row;
254             columnIndex = column;
255 
256             editRow = tableModel.getEntry(row);
257 
258             component.setText(editRow.getCaracteristics());
259             component.setToolTipText(editRow.getCaracteristics());
260 
261             return component;
262         }
263 
264         @Override
265         public Object getCellEditorValue() {
266 
267             Preconditions.checkNotNull(editRow, "No editRow found in editor.");
268 
269             return editRow.getCaracteristics();
270         }
271 
272         @Override
273         public void cancelCellEditing() {
274             super.cancelCellEditing();
275             rowIndex = null;
276             columnIndex = null;
277             editRow = null;
278         }
279     }
280 
281     public static class CaracteristicMapCellRenderer implements TableCellRenderer {
282 
283         protected final CaracteristicMapCellComponent component;
284 
285         public CaracteristicMapCellRenderer(TuttiUIContext context) {
286             component = new CaracteristicMapCellComponent(context);
287         }
288 
289         @Override
290         public Component getTableCellRendererComponent(JTable table,
291                                                        Object value,
292                                                        boolean isSelected,
293                                                        boolean hasFocus,
294                                                        int row,
295                                                        int column) {
296 
297             CaracteristicMapCellComponent result =
298                     (CaracteristicMapCellComponent) component.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
299 
300             boolean editable = table.isCellEditable(row, column);
301             result.setEnabled(editable);
302 
303             CaracteristicMap map = (CaracteristicMap) value;
304             result.setText(map);
305             result.setToolTipText(map);
306 
307             return result;
308         }
309     }
310 }