1 /*
2  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /* @test
25    @bug 6462562
26    @summary Tests text input into JFormattedTextField
27             with an InternationalFormatter
28    @author Peter Zhelezniakov
29    @run main Test6462562
30 */
31 
32 import java.awt.event.ActionEvent;
33 import java.text.DateFormat;
34 import java.text.NumberFormat;
35 import java.text.ParseException;
36 import java.text.SimpleDateFormat;
37 import java.util.Date;
38 import java.util.Locale;
39 import javax.swing.Action;
40 import javax.swing.JFormattedTextField;
41 import javax.swing.SwingUtilities;
42 import javax.swing.text.Caret;
43 import javax.swing.text.DateFormatter;
44 import javax.swing.text.DefaultEditorKit;
45 import javax.swing.text.InternationalFormatter;
46 import javax.swing.text.NumberFormatter;
47 
48 
49 public class Test6462562
50 {
51     static final String BACKSPACE = new String("backspace");
52     static final String DELETE = new String("delete");
53 
54     boolean failed = false;
55 
test()56     void test() {
57         testPercentFormat();
58         testCurrencyFormat();
59         testIntegerFormat();
60         testDateFormat();
61 
62         if (failed) {
63             throw new RuntimeException("Some testcases failed, see output above");
64         }
65         System.err.println("(-;  All testcases passed  ;-)");
66     }
67 
create(NumberFormat format)68     TestFormattedTextField create(NumberFormat format) {
69         format.setMaximumFractionDigits(0);
70         NumberFormatter fmt = new NumberFormatter(format);
71         return new TestFormattedTextField(fmt);
72     }
73 
create(DateFormat format)74     TestFormattedTextField create(DateFormat format) {
75         DateFormatter fmt = new DateFormatter(format);
76         return new TestFormattedTextField(fmt);
77     }
78 
main(String[] args)79     public static void main(String[] args) throws Exception {
80         SwingUtilities.invokeAndWait(new Runnable() {
81             public void run() {
82                 new Test6462562().test();
83             }
84         });
85     }
86 
87     class TestFormattedTextField extends JFormattedTextField
88     {
89         final Action backspace;
90         final Action delete;
91         final Action insert;
92 
93         final ActionEvent dummyEvent;
94 
TestFormattedTextField(InternationalFormatter fmt)95         public TestFormattedTextField(InternationalFormatter fmt) {
96             super(fmt);
97             fmt.setAllowsInvalid(false);
98             fmt.setOverwriteMode(true);
99 
100             backspace = getActionMap().get(DefaultEditorKit.deletePrevCharAction);
101             delete = getActionMap().get(DefaultEditorKit.deleteNextCharAction);
102             insert = getActionMap().get(DefaultEditorKit.insertContentAction);
103             dummyEvent = new ActionEvent(this, 0, null);
104         }
105 
test(int pos, int selectionLength, String todo, Object expectedResult)106         public boolean test(int pos, int selectionLength, String todo, Object expectedResult) {
107             Object v0 = getValue();
108 
109             Caret caret = getCaret();
110             caret.setDot(pos);
111             if (selectionLength > 0) {
112                 caret.moveDot(pos + selectionLength);
113             }
114 
115             String desc = todo;
116             if (todo == BACKSPACE) {
117                 backspace.actionPerformed(dummyEvent);
118             } else if (todo == DELETE) {
119                 delete.actionPerformed(dummyEvent);
120             } else {
121                 desc = "insert('" + todo + "')";
122                 insert.actionPerformed(new ActionEvent(this, 0, todo));
123             }
124 
125             try {
126                 commitEdit();
127             } catch (ParseException e) {
128                 e.printStackTrace();
129                 failed = true;
130                 return false;
131             }
132 
133             Object v1 = getValue();
134             if (! v1.equals(expectedResult)) {
135                 System.err.printf("Failure: value='%s', mark=%d, dot=%d, action=%s\n",
136                         v0, pos, pos + selectionLength, desc);
137                 System.err.printf("   Result: '%s', expected: '%s'\n", v1, expectedResult);
138                 failed = true;
139                 return false;
140             }
141             return true;
142         }
143     }
144 
testPercentFormat()145     void testPercentFormat() {
146         NumberFormat format = NumberFormat.getPercentInstance(Locale.US);
147         TestFormattedTextField ftf = create(format);
148         ftf.setValue(.34);
149 
150         System.err.println("Testing NumberFormat.getPercentInstance(Locale.US)");
151 
152         // test inserting individual characters
153         ftf.test(0, 0, "1", .14);
154         ftf.test(2, 0, "2", 1.42);
155         ftf.test(1, 0, "0", 1.02);
156 
157         // test inserting several characters at once - e.g. from clipboard
158         ftf.test(0, 0, "1024", 10.24);
159         ftf.test(3, 0, "333", 103.33);
160         ftf.test(6, 0, "77", 10333.77);
161         ftf.test(4, 0, "99", 10399.77);
162         ftf.test(6, 0, "00", 10390.07);
163 
164         // test inserting strings that contain some formatting
165         ftf.test(0, 0, "2,2", 2290.07);
166         ftf.test(2, 0, "2,2", 222.27);
167         ftf.test(4, 0, "2,2", 222.22);
168         ftf.test(6, 0, "33,33", 2222233.33);
169 
170         // test delete
171         ftf.test(0, 0, DELETE, 222233.33);
172         ftf.test(10, 0, DELETE, 222233.33);
173         ftf.test(5, 0, DELETE, 22223.33);
174         ftf.test(6, 0, DELETE, 2222.33);
175 
176         // test backspace
177         ftf.test(0, 0, BACKSPACE, 2222.33);
178         ftf.test(7, 0, BACKSPACE, 222.23);
179         ftf.test(4, 0, BACKSPACE, 22.23);
180         ftf.test(2, 0, BACKSPACE, 2.23);
181 
182         // test replacing selection
183         ftf.test(0, 1, "555", 555.23);
184         ftf.test(4, 2, "555", 5555.55);
185         ftf.test(2, 3, "1", 551.55);
186         ftf.test(3, 2, "6", 55.65);
187         ftf.test(4, 2, "12", 556.12);
188         ftf.test(3, 4, "0", 5.5);
189         ftf.test(0, 3, "111222333444555", 1112223334445.55);
190 
191         // test deleting selection
192         ftf.test(0, 2, DELETE, 12223334445.55);
193         ftf.test(0, 3, BACKSPACE, 223334445.55);
194         ftf.test(12, 2, DELETE, 2233344.45);
195         ftf.test(9, 2, BACKSPACE, 22333.44);
196         ftf.test(4, 3, DELETE, 223.44);
197         ftf.test(1, 2, BACKSPACE, 23.44);
198         ftf.test(3, 3, DELETE, .23);
199         ftf.test(1, 2, BACKSPACE, .02);
200     }
201 
testCurrencyFormat()202     void testCurrencyFormat() {
203         NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US);
204         TestFormattedTextField ftf = create(format);
205         ftf.setValue(56L);
206 
207         System.err.println("Testing NumberFormat.getCurrencyInstance(Locale.US)");
208 
209         // test inserting individual characters
210         ftf.test(1, 0, "1", 16L);
211         ftf.test(3, 0, "2", 162L);
212         ftf.test(2, 0, "0", 102L);
213 
214         // test inserting several characters at once - e.g. from clipboard
215         ftf.test(1, 0, "1024", 1024L);
216         ftf.test(4, 0, "333", 10333L);
217         ftf.test(7, 0, "77", 1033377L);
218         ftf.test(5, 0, "99", 1039977L);
219         ftf.test(7, 0, "00", 1039007L);
220 
221         // test inserting strings that contain some formatting
222         ftf.test(1, 0, "2,2", 229007L);
223         ftf.test(3, 0, "2,2", 22227L);
224         ftf.test(4, 0, "2,2", 2222L);
225         ftf.test(6, 0, "33,33", 22223333L);
226 
227         // test delete
228         ftf.test(1, 0, DELETE, 2223333L);
229         ftf.test(10, 0, DELETE, 2223333L);
230         ftf.test(5, 0, DELETE, 222333L);
231         ftf.test(5, 0, DELETE, 22233L);
232 
233         // test backspace
234         ftf.test(1, 0, BACKSPACE, 22233L);
235         ftf.test(7, 0, BACKSPACE, 2223L);
236         ftf.test(4, 0, BACKSPACE, 223L);
237         ftf.test(2, 0, BACKSPACE, 23L);
238 
239         // test replacing selection
240         ftf.test(1, 1, "555", 5553L);
241         ftf.test(4, 2, "555", 55555L);
242         ftf.test(2, 3, "1", 5155L);
243         ftf.test(3, 2, "6", 565L);
244         ftf.test(1, 3, "111222333444555", 111222333444555L);
245 
246         // test deleting selection
247         ftf.test(1, 2, DELETE, 1222333444555L);
248         ftf.test(1, 3, BACKSPACE, 22333444555L);
249         ftf.test(13, 2, DELETE, 223334445L);
250         ftf.test(10, 2, BACKSPACE, 2233344L);
251         ftf.test(4, 4, DELETE, 2244L);
252         ftf.test(1, 4, BACKSPACE, 4L);
253     }
254 
testIntegerFormat()255     void testIntegerFormat() {
256         NumberFormat format = NumberFormat.getIntegerInstance(Locale.US);
257         TestFormattedTextField ftf = create(format);
258         ftf.setValue(56L);
259 
260         System.err.println("Testing NumberFormat.getIntegerInstance(Locale.US)");
261 
262         // test inserting individual characters
263         ftf.test(0, 0, "1", 16L);
264         ftf.test(2, 0, "2", 162L);
265         ftf.test(1, 0, "0", 102L);
266 
267         // test inserting several characters at once - e.g. from clipboard
268         ftf.test(0, 0, "1024", 1024L);
269         ftf.test(3, 0, "333", 10333L);
270         ftf.test(6, 0, "77", 1033377L);
271         ftf.test(4, 0, "99", 1039977L);
272         ftf.test(6, 0, "00", 1039007L);
273 
274         // test inserting strings that contain some formatting
275         ftf.test(0, 0, "2,2", 229007L);
276         ftf.test(2, 0, "2,2", 22227L);
277         ftf.test(3, 0, "2,2", 2222L);
278         ftf.test(5, 0, "33,33", 22223333L);
279 
280         // test delete
281         ftf.test(0, 0, DELETE, 2223333L);
282         ftf.test(9, 0, DELETE, 2223333L);
283         ftf.test(4, 0, DELETE, 222333L);
284         ftf.test(4, 0, DELETE, 22233L);
285 
286         // test backspace
287         ftf.test(0, 0, BACKSPACE, 22233L);
288         ftf.test(6, 0, BACKSPACE, 2223L);
289         ftf.test(2, 0, BACKSPACE, 223L);
290         ftf.test(2, 0, BACKSPACE, 23L);
291 
292         // test replacing selection
293         ftf.test(0, 1, "555", 5553L);
294         ftf.test(3, 2, "555", 55555L);
295         ftf.test(1, 3, "1", 5155L);
296         ftf.test(2, 2, "6", 565L);
297         ftf.test(0, 3, "111222333444555", 111222333444555L);
298 
299         // test deleting selection
300         ftf.test(0, 2, DELETE, 1222333444555L);
301         ftf.test(0, 3, BACKSPACE, 22333444555L);
302         ftf.test(12, 2, DELETE, 223334445L);
303         ftf.test(9, 2, BACKSPACE, 2233344L);
304         ftf.test(3, 4, DELETE, 2244L);
305         ftf.test(0, 4, BACKSPACE, 4L);
306     }
307 
date(DateFormat format, String spec)308     Date date(DateFormat format, String spec) {
309         try {
310             return format.parse(spec);
311         } catch (ParseException e) {
312             throw new Error("Error in test");
313         }
314     }
315 
testDateFormat()316     void testDateFormat() {
317         DateFormat format = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
318         TestFormattedTextField ftf = create(format);
319         ftf.setValue(date(format, "12/05/2005"));
320 
321         System.err.println("Testing SimpleDateFormat(\"MM/dd/yyyy\", Locale.US)");
322 
323         // test inserting individual characters
324         ftf.test(0, 0, "0", date(format, "02/05/2005"));
325         ftf.test(4, 0, "4", date(format, "02/04/2005"));
326         ftf.test(6, 0, "1", date(format, "02/04/1005"));
327         ftf.test(9, 0, "9", date(format, "02/04/1009"));
328 
329         // test inserting several characters at once - e.g. from clipboard
330         ftf.test(0, 0, "11", date(format, "11/04/1009"));
331         ftf.test(3, 0, "23", date(format, "11/23/1009"));
332         ftf.test(6, 0, "191", date(format, "11/23/1919"));
333 
334         // test delete
335         ftf.test(0, 0, DELETE, date(format, "01/23/1919"));
336         ftf.test(3, 0, DELETE, date(format, "01/03/1919"));
337         ftf.test(10, 0, DELETE, date(format, "01/03/1919"));
338         ftf.test(1, 0, DELETE, date(format, "12/03/1918"));
339         ftf.test(4, 0, DELETE, date(format, "11/30/1918"));
340 
341         // test backspace
342         ftf.test(0, 0, BACKSPACE, date(format, "11/30/1918"));
343         ftf.test(1, 0, BACKSPACE, date(format, "01/30/1918"));
344         ftf.test(4, 0, BACKSPACE, date(format, "12/31/1917"));
345         ftf.test(10, 0, BACKSPACE, date(format, "12/31/0191"));
346         ftf.test(3, 0, BACKSPACE, date(format, "01/31/0191"));
347         ftf.test(5, 0, BACKSPACE, date(format, "01/03/0191"));
348 
349         // test replacing selection
350         ftf.test(0, 1, "1", date(format, "11/03/0191"));
351         ftf.test(3, 1, "2", date(format, "11/23/0191"));
352         ftf.test(6, 2, "20", date(format, "11/23/2091"));
353 
354         // test deleting selection
355         ftf.test(0, 1, BACKSPACE, date(format, "01/23/2091"));
356         ftf.test(3, 1, DELETE, date(format, "01/03/2091"));
357         ftf.test(6, 2, BACKSPACE, date(format, "01/03/0091"));
358         ftf.test(8, 1, DELETE, date(format, "01/03/0001"));
359     }
360 }
361