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 @ 272

History | View | Annotate | Download (7.97 KB)

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

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

    
9
import javax.swing.JComboBox;
10
import javax.swing.JFrame;
11
import javax.swing.JLabel;
12

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

    
20

    
21
/**
22
 * A panel to select the format for a decimal number. The following options are
23
 * offered:
24
 * <ul>
25
 * <li>The decimal separator character</li>
26
 * <li>The thousands separator character</li>
27
 * <li>The number of decimal digits. Note that this component forces the
28
 * maximum and minimum number of decimal digits (as defined in {@link DecimalFormat})
29
 * to be always equal.</li>
30
 * </ul>
31
 * 
32
 * @author Cesar Martinez Izquierdo
33
 */
34
public class DecimalFormatPanel extends GridBagLayoutPanel {
35
        private static final long serialVersionUID = 1L;
36
        public static final String INTEGER_BASE_PATTERN = "0";
37
        public static final String INTEGER_GROUPED_BASE_PATTERN = "#,###,###,###,###,###,##0";
38
        public static final String DECIMAL_BASE_PATTERN = "#0.";
39
        public static final String DECIMAL_GROUPED_BASE_PATTERN = "#,###,###,###,###,###,##0.";
40
        private DecimalFormat format;
41
        private CharComboBox cbDecimalSep = null;
42
        private CharComboBox cbThousandsSep = null;
43
        private JIncrementalNumberField tfDecimalDigits = null;
44
        private JLabel lbResult = null;
45
        private double testNumber = 123456789.00;
46
        private static final DecimalFormatSymbols defaultLocaleSymbols = DecimalFormatSymbols.getInstance();
47
        
48
        /**
49
         * Creates and initializes the panel using the default format
50
         *  for the current locale
51
         */
52
        public DecimalFormatPanel() {
53
                this(new DecimalFormat());
54
        }
55
        
56
        /**
57
         * Creates and initializes the panel using the provided
58
         * DecimalFormat 
59
         */
60
        public DecimalFormatPanel(DecimalFormat format) {
61
                super();
62
                initComponents();
63
                setFormat(format);
64
        }
65
        
66
        /**
67
         * Creates and initializes the panel using the provided parameters
68
         * 
69
         * @param decimalSeparator The character used to separate the decimal part
70
         * @param thousandsSeparator The character used to group thousands
71
         * @param decimalDigits The number of decimal digits to show
72
         * @param basePattern A base pattern used to create the DecimalFormat.
73
         * Usually, one of {@link #INTEGER_BASE_PATTERN},
74
         * {@link #INTEGER_GROUPED_BASE_PATTERN}, {@link #DECIMAL_BASE_PATTERN}
75
         * or {@link #DECIMAL_GROUPED_BASE_PATTERN}.
76
         * Any decimal digits in the pattern will be ignored (as they will be
77
         * included depending on the <code>decimalDigits</code> parameter). The
78
         * behavior of the component is undefined if a wrong pattern is provided
79
         * 
80
         * @see DecimalFormat
81
         */
82
        public DecimalFormatPanel(char decimalSeparator, char thousandsSeparator, int decimalDigits, String basePattern) {
83
                super();
84
                initComponents();
85
                DecimalFormatSymbols sym = new DecimalFormatSymbols();
86
                sym.setDecimalSeparator(decimalSeparator);
87
                sym.setGroupingSeparator(thousandsSeparator);
88
                String pattern = getPattern(basePattern, decimalDigits);
89
                DecimalFormat f = new DecimalFormat(pattern, sym);
90
                setFormat(f);
91
        }
92
        
93
        protected void initComponents() {
94
                this.addComponent(Messages.getText("Decimal_separator"), getCbDecimalSep());
95
                this.addComponent(Messages.getText("Thousands_separator"), getCbThousandsSep());
96
                this.addComponent(Messages.getText("Decimal_digits"), getTfDecimalDigits());
97
                this.addComponent(Messages.getText("Result"), getLbTestResult());
98
                
99
        }
100
        
101
        private String getPattern(String basePattern, int decimalDigits) {
102
                int pos = basePattern.indexOf('.');
103
                if (pos>=0) {
104
                        basePattern = basePattern.substring(0, pos+1);
105
                }
106
                if (decimalDigits>0) {
107
                        return basePattern + String.format(("%1$0"+decimalDigits+"d"),0);
108
                }
109
                else {
110
                        return basePattern;
111
                }
112
        }
113
        
114
        
115
        private CharComboBox getCbDecimalSep() {
116
                if (cbDecimalSep==null) {
117
                        cbDecimalSep = new CharComboBox(new String[]{".", ","}, false);
118
                        cbDecimalSep.addActionListener(new ActionListener() {
119
                                public void actionPerformed(ActionEvent e) {
120
                                        if (e.getSource() instanceof CharComboBox) {
121
                                                DecimalFormatPanel.this.updateFormat(e.getSource());
122
                                        }
123
                                }
124
                        });
125
                }
126
                return cbDecimalSep;
127
        }
128
        
129
        private CharComboBox getCbThousandsSep() {
130
                if (cbThousandsSep==null) {
131
                        cbThousandsSep = new CharComboBox(new String[]{",", ".", " "}, true);
132
                        cbThousandsSep.addActionListener(new ActionListener() {
133
                                public void actionPerformed(ActionEvent e) {
134
                                        if (e.getSource() instanceof CharComboBox) {
135
                                                DecimalFormatPanel.this.updateFormat(e.getSource());
136
                                        }
137
                                }
138
                        });
139
                }
140
                return cbThousandsSep;
141
        }
142
        
143
        protected void updateFormat(Object source) {
144
                // get selected values
145
                String thousandsSeparator = getCbThousandsSep().getSelectedItem();
146
                String decimalSeparator = getCbDecimalSep().getSelectedItem();
147
                int decimalDigits = getTfDecimalDigits().getInteger();
148
                boolean b_decimalSep, b_thousandsSep;
149
                DecimalFormatSymbols sym = format.getDecimalFormatSymbols();
150
                if (decimalSeparator!=null && decimalSeparator.length()>0) {
151
                        sym.setDecimalSeparator(decimalSeparator.charAt(0));
152
                        b_decimalSep = true;
153
                }
154
                else {
155
                        b_decimalSep = false;
156
                }
157
                if (thousandsSeparator!=null && 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
                getTfDecimalDigits().setInteger(format.getMinimumFractionDigits());
234
                
235
                String decSep = String.valueOf(format.getDecimalFormatSymbols().getDecimalSeparator());
236
                selectItem(getCbDecimalSep(), decSep);
237
                
238
                String thousandsSep = String.valueOf(format.getDecimalFormatSymbols().getGroupingSeparator());
239
                selectItem(getCbThousandsSep(), thousandsSep);
240
        }
241
        
242
        /**
243
         * Adds the provided item to the combo if it is not already present,
244
         * then selects it.
245
         * 
246
         * @param cb
247
         * @param item
248
         * @return
249
         */
250
        private void selectItem(JComboBox cb, String item) {
251
                for (int i=0; i<cb.getItemCount(); i++) {
252
                        if (cb.getItemAt(i).equals(item)) {
253
                                cb.setSelectedItem(item);
254
                                return;
255
                        }
256
                }
257
                cb.addItem(item);
258
                cb.setSelectedItem(item);
259
        }
260
}