1 package fr.ifremer.tutti.ui.swing.util.computable;
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.type.WeightUnit;
26 import fr.ifremer.tutti.ui.swing.util.TuttiUI;
27 import jaxx.runtime.JAXXUtil;
28
29 import javax.swing.AbstractCellEditor;
30 import javax.swing.JLabel;
31 import javax.swing.JTable;
32 import javax.swing.SwingConstants;
33 import javax.swing.SwingUtilities;
34 import javax.swing.border.LineBorder;
35 import javax.swing.event.AncestorEvent;
36 import javax.swing.event.AncestorListener;
37 import javax.swing.table.DefaultTableCellRenderer;
38 import javax.swing.table.TableCellEditor;
39 import javax.swing.table.TableCellRenderer;
40 import java.awt.Color;
41 import java.awt.Component;
42 import java.awt.Font;
43 import java.awt.event.FocusEvent;
44 import java.awt.event.FocusListener;
45 import java.io.Serializable;
46
47
48
49
50
51
52
53 public class ComputableDataTableCell extends DefaultTableCellRenderer {
54 private static final long serialVersionUID = 1L;
55
56 public static TableCellRenderer newRender(TableCellRenderer renderer, WeightUnit weightUnit, Color computedDataColor) {
57
58 return new TuttiComputedOrNotDataTableCellRenderer(weightUnit, renderer, computedDataColor);
59 }
60
61 public static TableCellEditor newEditor(WeightUnit weightUnit, Color computedDataColor) {
62
63 return new TuttiComputedOrNotDataTableCellEditor(weightUnit, computedDataColor);
64 }
65
66 public static class TuttiComputedOrNotDataTableCellEditor extends AbstractCellEditor implements TableCellEditor, FocusListener, AncestorListener {
67
68 private static final long serialVersionUID = 1L;
69
70 private final ComputableDataEditor<Float> numberEditor;
71
72 private ComputableData<Float> data;
73
74
75 public TuttiComputedOrNotDataTableCellEditor(WeightUnit weightUnit, Color computedDataColor) {
76
77 numberEditor = new ComputableDataEditor<>();
78 numberEditor.setComputedDataColor(computedDataColor);
79 numberEditor.getTextField().setHorizontalAlignment(SwingConstants.RIGHT);
80 numberEditor.getTextField().addFocusListener(this);
81 numberEditor.getTextField().addAncestorListener(this);
82 numberEditor.getTextField().setBorder(new LineBorder(Color.GRAY, 2));
83 numberEditor.setSelectAllTextOnError(true);
84
85 numberEditor.setNumberType(Float.class);
86 numberEditor.setUseSign(false);
87 numberEditor.init();
88 numberEditor.setWeightUnit(weightUnit);
89 }
90
91 @Override
92 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
93
94 data = (ComputableData<Float>) value;
95 numberEditor.setNumberValue(data.getData());
96
97
98
99
100
101
102 return numberEditor;
103 }
104
105 public ComputableDataEditor getNumberEditor() {
106 return numberEditor;
107 }
108
109 @Override
110 public ComputableData<Float> getCellEditorValue() {
111 return data;
112 }
113
114 @Override
115 public void focusGained(FocusEvent e) {
116 SwingUtilities.invokeLater(() -> {
117 numberEditor.getTextField().requestFocus();
118 numberEditor.getTextField().selectAll();
119 });
120 }
121
122 @Override
123 public void focusLost(FocusEvent e) {
124 }
125
126 @Override
127 public void ancestorAdded(AncestorEvent event) {
128 SwingUtilities.invokeLater(() -> {
129 numberEditor.getTextField().requestFocus();
130 numberEditor.getTextField().selectAll();
131 });
132 }
133
134 @Override
135 public void ancestorRemoved(AncestorEvent event) {
136 }
137
138 @Override
139 public void ancestorMoved(AncestorEvent event) {
140 }
141
142 @Override
143 public boolean stopCellEditing() {
144 boolean result = super.stopCellEditing();
145
146 if (result) {
147 data.setData((Float) numberEditor.getModel().getNumberValue());
148
149 numberEditor.setBean((Serializable) null);
150
151 data = null;
152 }
153 return result;
154 }
155 }
156
157 private static class TuttiComputedOrNotDataTableCellRenderer implements TableCellRenderer {
158
159 private final WeightUnit weightUnit;
160
161 protected final TableCellRenderer delegate;
162
163
164
165 protected Color computedDataColor;
166
167
168
169 private TuttiComputedOrNotDataTableCellRenderer(WeightUnit weightUnit,
170 TableCellRenderer delegate,
171
172
173 Color computedDataColor) {
174 this.weightUnit = weightUnit;
175 this.delegate = delegate;
176
177
178 this.computedDataColor = computedDataColor;
179 }
180
181 @Override
182 public Component getTableCellRendererComponent(JTable table,
183 Object value,
184 boolean isSelected,
185 boolean hasFocus,
186 int row,
187 int column) {
188
189 ComputableData<Float> data = (ComputableData<Float>) value;
190 Float dataValue = data.getData();
191 Font font;
192 Color foreground;
193 String text;
194 if (dataValue == null) {
195 dataValue = data.getComputedData();
196 font = TuttiUI.TEXTFIELD_COMPUTED_FONT;
197 foreground = computedDataColor;
198
199 text = weightUnit.renderWeight(dataValue);
200
201
202
203
204
205
206
207
208
209 } else {
210 font = TuttiUI.TEXTFIELD_NORMAL_FONT;
211 foreground = Color.BLACK;
212 text = JAXXUtil.getStringValue(dataValue);
213 }
214
215 Component component = delegate.getTableCellRendererComponent(table,
216 text,
217 isSelected,
218 hasFocus,
219 row,
220 column);
221
222 if (isSelected) {
223 font = font.deriveFont(Font.BOLD);
224 }
225 component.setFont(font);
226 component.setForeground(foreground);
227 if (component instanceof JLabel) {
228 JLabel jLabel = (JLabel) component;
229 jLabel.setHorizontalAlignment(RIGHT);
230 }
231
232 return component;
233 }
234
235 }
236
237 }