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
32import java.awt.event.ActionEvent;
33import java.text.DateFormat;
34import java.text.NumberFormat;
35import java.text.ParseException;
36import java.text.SimpleDateFormat;
37import java.util.Date;
38import java.util.Locale;
39import javax.swing.Action;
40import javax.swing.JFormattedTextField;
41import javax.swing.SwingUtilities;
42import javax.swing.text.Caret;
43import javax.swing.text.DateFormatter;
44import javax.swing.text.DefaultEditorKit;
45import javax.swing.text.InternationalFormatter;
46import javax.swing.text.NumberFormatter;
47
48
49public 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
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
68    TestFormattedTextField create(NumberFormat format) {
69        format.setMaximumFractionDigits(0);
70        NumberFormatter fmt = new NumberFormatter(format);
71        return new TestFormattedTextField(fmt);
72    }
73
74    TestFormattedTextField create(DateFormat format) {
75        DateFormatter fmt = new DateFormatter(format);
76        return new TestFormattedTextField(fmt);
77    }
78
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
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
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
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
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
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
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
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