Statistics
| Revision:

svn-document-layout / trunk / org.gvsig.app.document.layout2.app / org.gvsig.app.document.layout2.app.mainplugin / src / main / java / org / gvsig / app / project / documents / layout / fframes / gui / numberFormat / DecimalFormatPanel.java @ 274

History | View | Annotate | Download (8.14 KB)

1
package org.gvsig.app.project.documents.layout.fframes.gui.numberFormat;
2

    
3
import java.awt.event.ActionEvent;
4
import java.awt.event.ActionListener;
5
import java.text.DecimalFormat;
6
import java.text.DecimalFormatSymbols;
7

    
8
import javax.swing.JComboBox;
9
import javax.swing.JLabel;
10

    
11
import org.gvsig.gui.beans.swing.GridBagLayoutPanel;
12
import org.gvsig.gui.beans.swing.JIncrementalNumberField;
13
import org.gvsig.gui.beans.swing.ValidatingTextField;
14
import org.gvsig.gui.beans.swing.ValidatingTextField.Cleaner;
15
import org.gvsig.gui.beans.swing.ValidatingTextField.Validator;
16
import org.gvsig.i18n.Messages;
17

    
18

    
19
/**
20
 * A panel to select the format for a decimal number. The following options are
21
 * offered:
22
 * <ul>
23
 * <li>The decimal separator character</li>
24
 * <li>The thousands separator character</li>
25
 * <li>The number of decimal digits. Note that this component forces the
26
 * maximum and minimum number of decimal digits (as defined in {@link DecimalFormat})
27
 * to be always equal.</li>
28
 * </ul>
29
 * 
30
 * @author Cesar Martinez Izquierdo
31
 */
32
public class DecimalFormatPanel extends GridBagLayoutPanel {
33
        private static final long serialVersionUID = 1L;
34
        public static final String INTEGER_BASE_PATTERN = "0";
35
        public static final String INTEGER_GROUPED_BASE_PATTERN = "#,###,###,###,###,###,##0";
36
        public static final String DECIMAL_BASE_PATTERN = "#0.";
37
        public static final String DECIMAL_GROUPED_BASE_PATTERN = "#,###,###,###,###,###,##0.";
38
        private DecimalFormat format;
39
        private CharComboBox cbDecimalSep = null;
40
        private CharComboBox cbThousandsSep = null;
41
        private JIncrementalNumberField tfDecimalDigits = null;
42
        private JLabel lbResult = null;
43
        private double testNumber = 123456789.00;
44
        private static final DecimalFormatSymbols defaultLocaleSymbols = DecimalFormatSymbols.getInstance();
45
        
46
        /**
47
         * Creates and initializes the panel using the default format
48
         *  for the current locale
49
         */
50
        public DecimalFormatPanel() {
51
                this(new DecimalFormat());
52
        }
53
        
54
        /**
55
         * Creates and initializes the panel using the provided
56
         * DecimalFormat 
57
         */
58
        public DecimalFormatPanel(DecimalFormat format) {
59
                super();
60
                initComponents();
61
                setFormat(format);
62
        }
63
        
64
        /**
65
         * Creates and initializes the panel using the provided parameters
66
         * 
67
         * @param decimalSeparator The character used to separate the decimal part
68
         * @param thousandsSeparator The character used to group thousands
69
         * @param decimalDigits The number of decimal digits to show
70
         * @param basePattern A base pattern used to create the DecimalFormat.
71
         * Usually, one of {@link #INTEGER_BASE_PATTERN},
72
         * {@link #INTEGER_GROUPED_BASE_PATTERN}, {@link #DECIMAL_BASE_PATTERN}
73
         * or {@link #DECIMAL_GROUPED_BASE_PATTERN}.
74
         * Any decimal digits in the pattern will be ignored (as they will be
75
         * included depending on the <code>decimalDigits</code> parameter). The
76
         * behavior of the component is undefined if a wrong pattern is provided
77
         * 
78
         * @see DecimalFormat
79
         */
80
        public DecimalFormatPanel(char decimalSeparator, char thousandsSeparator, int decimalDigits, String basePattern) {
81
                super();
82
                initComponents();
83
                DecimalFormatSymbols sym = new DecimalFormatSymbols();
84
                sym.setDecimalSeparator(decimalSeparator);
85
                sym.setGroupingSeparator(thousandsSeparator);
86
                String pattern = getPattern(basePattern, decimalDigits);
87
                DecimalFormat f = new DecimalFormat(pattern, sym);
88
                setFormat(f);
89
        }
90
        
91
        protected void initComponents() {
92
                this.addComponent(Messages.getText("Decimal_separator"), getCbDecimalSep());
93
                this.addComponent(Messages.getText("Thousands_separator"), getCbThousandsSep());
94
                this.addComponent(Messages.getText("Decimal_digits"), getTfDecimalDigits());
95
                this.addComponent(Messages.getText("Result"), getLbTestResult());
96
                
97
        }
98
        
99
        private String getPattern(String basePattern, int decimalDigits) {
100
                int pos = basePattern.indexOf('.');
101
                if (pos>=0) {
102
                        basePattern = basePattern.substring(0, pos+1);
103
                }
104
                if (decimalDigits>0) {
105
                        return basePattern + String.format(("%1$0"+decimalDigits+"d"),0);
106
                }
107
                else {
108
                        return basePattern;
109
                }
110
        }
111
        
112
        
113
        private CharComboBox getCbDecimalSep() {
114
                if (cbDecimalSep==null) {
115
                        cbDecimalSep = new CharComboBox(new String[]{".", ","}, false);
116
                        cbDecimalSep.addActionListener(new ActionListener() {
117
                                public void actionPerformed(ActionEvent e) {
118
                                        if (e.getSource() instanceof CharComboBox) {
119
                                                DecimalFormatPanel.this.updateFormat(e.getSource());
120
                                        }
121
                                }
122
                        });
123
                }
124
                return cbDecimalSep;
125
        }
126
        
127
        private CharComboBox getCbThousandsSep() {
128
                if (cbThousandsSep==null) {
129
                        cbThousandsSep = new CharComboBox(new String[]{",", ".", " "}, true);
130
                        cbThousandsSep.addActionListener(new ActionListener() {
131
                                public void actionPerformed(ActionEvent e) {
132
                                        if (e.getSource() instanceof CharComboBox) {
133
                                                DecimalFormatPanel.this.updateFormat(e.getSource());
134
                                        }
135
                                }
136
                        });
137
                }
138
                return cbThousandsSep;
139
        }
140
        
141
        protected void updateFormat(Object source) {
142
                // get selected values
143
                String thousandsSeparator = getCbThousandsSep().getSelectedItem();
144
                String decimalSeparator = getCbDecimalSep().getSelectedItem();
145
                int decimalDigits = getTfDecimalDigits().getInteger();
146
                boolean b_decimalSep, b_thousandsSep;
147
                DecimalFormatSymbols sym = format.getDecimalFormatSymbols();
148
                if (decimalSeparator!=null && decimalSeparator.length()>0) {
149
                        sym.setDecimalSeparator(decimalSeparator.charAt(0));
150
                        b_decimalSep = true;
151
                }
152
                else {
153
                        b_decimalSep = false;
154
                }
155
                if (thousandsSeparator!=null &&
156
                                thousandsSeparator!=getCbThousandsSep().getNoneItem() &&
157
                                thousandsSeparator.length()>0) {
158
                        sym.setGroupingSeparator(thousandsSeparator.charAt(0));
159
                        b_thousandsSep = true;
160
                }
161
                else {
162
                        b_thousandsSep = false;
163
                }
164
                
165
                // choose the right pattern
166
                String pattern = null;
167
                if (b_decimalSep && decimalDigits>0) {
168
                        if (b_thousandsSep) {
169
                                pattern = getPattern(DECIMAL_GROUPED_BASE_PATTERN, decimalDigits);
170
                        }
171
                        else {
172
                                pattern = getPattern(DECIMAL_BASE_PATTERN, decimalDigits);
173
                        }
174
                }
175
                else {
176
                        if (b_thousandsSep) {
177
                                pattern = INTEGER_GROUPED_BASE_PATTERN;
178
                        }
179
                        else {
180
                                pattern = INTEGER_BASE_PATTERN;
181
                        }
182
                }
183
                
184
                // update the format
185
                this.format = new DecimalFormat(pattern, sym);
186
                getLbTestResult().setText(this.format.format(testNumber));
187
                
188
                // set coherent options in UI
189
                if (source==getCbDecimalSep()) {
190
                        if (!b_decimalSep) {
191
                                // if no decimal separator is shown at all, we can't
192
                                // have any decimal digit
193
                                getTfDecimalDigits().setInteger(0);
194
                        }        
195
                }
196
                else {
197
                        if (decimalDigits>0 && !b_decimalSep) {
198
                                selectItem(getCbDecimalSep(), String.valueOf(defaultLocaleSymbols.getDecimalSeparator()));
199
                        }
200
                }
201
        }             
202
        
203
        private JIncrementalNumberField getTfDecimalDigits() {
204
                if (tfDecimalDigits==null) {
205
                        Cleaner cleaner = ValidatingTextField.NUMBER_CLEANER;
206
                        Validator validator = ValidatingTextField.INTEGER_VALIDATOR;
207
                        tfDecimalDigits = new JIncrementalNumberField("Decimal digits", 2, validator, cleaner, 0.0d, 100.0d, 1.0);
208
                        tfDecimalDigits.addActionListener(new ActionListener() {
209

    
210
                                public void actionPerformed(ActionEvent e) {
211
                                        DecimalFormatPanel.this.updateFormat(e.getSource());
212
                                }
213
                                
214
                        });
215
                }
216
                return tfDecimalDigits;
217
        }
218
        
219
        private JLabel getLbTestResult() {
220
                if (lbResult==null) {
221
                        String text;
222
                        lbResult = new JLabel();
223
                }
224
                return lbResult;
225
        }
226
        
227
        public DecimalFormat getFormat() {
228
                return format;
229
        }
230
        
231
        public void setFormat(DecimalFormat format) {
232
                this.format = format;
233
                boolean groupingUsed = format.isGroupingUsed();
234
                getTfDecimalDigits().setInteger(format.getMinimumFractionDigits());
235
                
236
                String decSep = String.valueOf(format.getDecimalFormatSymbols().getDecimalSeparator());
237
                selectItem(getCbDecimalSep(), decSep);
238
                
239
                if (groupingUsed) {
240
                        String thousandsSep = String.valueOf(format.getDecimalFormatSymbols().getGroupingSeparator());
241
                        selectItem(getCbThousandsSep(), thousandsSep);
242
                }
243
                else {
244
                        selectItem(getCbThousandsSep(), getCbThousandsSep().getNoneItem());
245
                }
246
        }
247
        
248
        /**
249
         * Adds the provided item to the combo if it is not already present,
250
         * then selects it.
251
         * 
252
         * @param cb
253
         * @param item
254
         * @return
255
         */
256
        private void selectItem(JComboBox cb, String item) {
257
                for (int i=0; i<cb.getItemCount(); i++) {
258
                        if (cb.getItemAt(i).equals(item)) {
259
                                cb.setSelectedItem(item);
260
                                return;
261
                        }
262
                }
263
                cb.addItem(item);
264
                cb.setSelectedItem(item);
265
        }
266
}