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

History | View | Annotate | Download (7.75 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.JNumberSpinner;
13
import org.gvsig.i18n.Messages;
14

    
15

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

    
205
                                public void actionPerformed(ActionEvent e) {
206
                                        DecimalFormatPanel.this.updateFormat(e.getSource());
207
                                }
208
                                
209
                        });
210
                }
211
                return tfDecimalDigits;
212
        }
213
        
214
        private JLabel getLbTestResult() {
215
                if (lbResult==null) {
216
                        lbResult = new JLabel();
217
                }
218
                return lbResult;
219
        }
220
        
221
        public DecimalFormat getFormat() {
222
                return format;
223
        }
224
        
225
        public void setFormat(DecimalFormat format) {
226
                this.format = format;
227
                boolean groupingUsed = format.isGroupingUsed();
228
                getTfDecimalDigits().setInteger(format.getMinimumFractionDigits());
229
                
230
                String decSep = String.valueOf(format.getDecimalFormatSymbols().getDecimalSeparator());
231
                selectItem(getCbDecimalSep(), decSep);
232
                
233
                if (groupingUsed) {
234
                        String thousandsSep = String.valueOf(format.getDecimalFormatSymbols().getGroupingSeparator());
235
                        selectItem(getCbThousandsSep(), thousandsSep);
236
                }
237
                else {
238
                        selectItem(getCbThousandsSep(), getCbThousandsSep().getNoneItem());
239
                }
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
}