View Javadoc
1   package fr.ifremer.tutti.ui.swing.util.computable;
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 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   * Editor for TuttiComputedOrNotData
49   *
50   * @author Kevin Morin - kmorin@codelutin.com
51   * @since 1.0
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          /** constructor */
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              // Check nullity and set the text that will be selected with the current value
98              //FIXME NumberEditor
99  //            if (data.getData() != null) {
100 //                numberEditor.getModel().setTextValue(String.valueOf(data.getData()));
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             // Reset previous data to avoid keeping it on other cell edition
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 //        protected Integer decimalNumber;
164 
165         protected Color computedDataColor;
166 
167 //        protected boolean useFloat;
168 
169         private TuttiComputedOrNotDataTableCellRenderer(WeightUnit weightUnit,
170                                                         TableCellRenderer delegate,
171 //                                                       boolean useFloat,
172 //                                                       Integer decimalNumber,
173                                                         Color computedDataColor) {
174             this.weightUnit = weightUnit;
175             this.delegate = delegate;
176 //            this.useFloat = useFloat;
177 //            this.decimalNumber = decimalNumber;
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 //                if (useFloat && decimalNumber != null && dataValue != null) {
202 //                    DecimalFormat decimalFormat = Weights.getDecimalFormat(1, decimalNumber);
203 //                    text = JAXXUtil.getStringValue(decimalFormat.format(dataValue));
204 //                    text = weightUnit.renderWeight((Float) dataValue);
205 //                } else {
206 //                    text = JAXXUtil.getStringValue(dataValue);
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 }