Source Code Cross Referenced for FormatChooser.java in  » GIS » GeoTools-2.4.1 » org » geotools » gui » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoTools 2.4.1 » org.geotools.gui.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         *    GeoTools - OpenSource mapping toolkit
003:         *    http://geotools.org
004:         *    (C) 2003-2006, Geotools Project Managment Committee (PMC)
005:         *    (C) 2003, Institut de Recherche pour le Développement
006:         *
007:         *    This library is free software; you can redistribute it and/or
008:         *    modify it under the terms of the GNU Lesser General Public
009:         *    License as published by the Free Software Foundation; either
010:         *    version 2.1 of the License, or (at your option) any later version.
011:         *
012:         *    This library is distributed in the hope that it will be useful,
013:         *    but WITHOUT ANY WARRANTY; without even the implied warranty of
014:         *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015:         *    Lesser General Public License for more details.
016:         */
017:        package org.geotools.gui.swing;
018:
019:        // J2SE dependencies
020:        import java.util.Set;
021:        import java.util.Map;
022:        import java.util.Date;
023:        import java.util.Locale;
024:        import java.util.HashMap;
025:        import java.util.LinkedHashSet;
026:        import java.text.Format;
027:        import java.text.DateFormat;
028:        import java.text.NumberFormat;
029:        import java.text.DecimalFormat;
030:        import java.text.SimpleDateFormat;
031:
032:        // Swing and AWT dependencies
033:        import javax.swing.JPanel;
034:        import javax.swing.JLabel;
035:        import javax.swing.JFrame;
036:        import javax.swing.JComboBox;
037:        import javax.swing.MutableComboBoxModel;
038:        import javax.swing.DefaultComboBoxModel;
039:        import javax.swing.BorderFactory;
040:        import java.awt.Color;
041:        import java.awt.Component;
042:        import java.awt.GridBagLayout;
043:        import java.awt.GridBagConstraints;
044:        import java.awt.event.ActionEvent;
045:        import java.awt.event.ActionListener;
046:
047:        // Geotools dependencies
048:        import org.geotools.measure.Angle;
049:        import org.geotools.measure.AngleFormat;
050:        import org.geotools.measure.CoordinateFormat;
051:        import org.geotools.geometry.GeneralDirectPosition;
052:        import org.geotools.resources.Arguments;
053:        import org.geotools.resources.Utilities;
054:        import org.geotools.resources.SwingUtilities;
055:        import org.geotools.resources.i18n.Vocabulary;
056:        import org.geotools.resources.i18n.VocabularyKeys;
057:
058:        /**
059:         * Select the pattern to use for {@linkplain Format formating} numbers, angles or dates.
060:         * This widget can be used with one of {@link Format} objects working with pattern, like
061:         * {@link DecimalFormat}, {@link SimpleDateFormat} or {@link AngleFormat}.
062:         *
063:         * @since 2.0
064:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/widgets-swing/src/main/java/org/geotools/gui/swing/FormatChooser.java $
065:         * @version $Id: FormatChooser.java 23632 2006-12-29 22:13:51Z desruisseaux $
066:         * @author Martin Desruisseaux
067:         */
068:        public class FormatChooser extends JPanel {
069:            /**
070:             * The maximum number of items to keep in the history list.
071:             */
072:            private static final int HISTORY_SIZE = 50;
073:
074:            /**
075:             * The color for error message.
076:             */
077:            private static final Color ERROR_COLOR = Color.RED;
078:
079:            /**
080:             * A set of default patterns for differents locales. Keys are {@link Locale} object
081:             * and values are {@code String[][]} with arrays in the following order: number
082:             * patterns, date patterns and angle patterns.
083:             */
084:            private static final Map PATTERNS = new HashMap();
085:
086:            /**
087:             * A set of default pattern for {@link AngleFormat}.
088:             */
089:            private static final String[] ANGLE_PATTERNS = new String[] {
090:                    "D.d°", "D.dd°", "D.ddd°", "D°MM'", "D°MM.m'", "D°MM.mm'",
091:                    "D°MM.mmm'", "D°MM'SS\"", "D°MM'SS.s\"" };
092:
093:            /**
094:             * The format to configure by this {@code FormatChooser}.
095:             */
096:            protected Format format;
097:
098:            /**
099:             * A sample value for the "preview" text.
100:             */
101:            private Object value;
102:
103:            /**
104:             * The panel in which to edit the pattern.
105:             */
106:            private final JComboBox choices = new JComboBox();
107:
108:            /**
109:             * The preview text. This is the {@code value} formated using {@code format}.
110:             */
111:            private final JLabel preview = new JLabel();
112:
113:            /**
114:             * Constructs a pattern chooser for the given format.
115:             *
116:             * @param  format The format to configure. The default implementation accept instance of
117:             *                {@link DecimalFormat}, {@link SimpleDateFormat} or {@link AngleFormat}.
118:             * @throws IllegalArgumentException if the format is invalid.
119:             */
120:            public FormatChooser(final Format format)
121:                    throws IllegalArgumentException {
122:                super (new GridBagLayout());
123:                final String[] patterns = getPatterns(format);
124:                if (patterns != null) {
125:                    final MutableComboBoxModel model = (MutableComboBoxModel) choices
126:                            .getModel();
127:                    for (int i = 0; i < patterns.length; i++) {
128:                        model.addElement(patterns[i]);
129:                    }
130:                }
131:                choices.setEditable(true); // Must be invoked before 'setFormat'.
132:                value = suggestSampleValue(format);
133:                setFormat(format);
134:
135:                final Vocabulary resources = Vocabulary
136:                        .getResources(getDefaultLocale());
137:                final GridBagConstraints c = new GridBagConstraints();
138:                c.gridx = 0;
139:                c.insets.right = 6;
140:                c.gridy = 0;
141:                add(new JLabel(resources.getLabel(VocabularyKeys.FORMAT)), c);
142:                c.gridy++;
143:                c.insets.top = 3;
144:                add(new JLabel(resources.getLabel(VocabularyKeys.PREVIEW)), c);
145:                c.insets.right = 0;
146:                c.gridx++;
147:                c.weightx = 1;
148:                c.fill = c.HORIZONTAL;
149:                c.gridy = 0;
150:                c.insets.top = 0;
151:                add(choices, c);
152:                c.gridy++;
153:                c.insets.top = 3;
154:                add(preview, c);
155:                choices.getEditor().getEditorComponent().requestFocus();
156:                choices.addActionListener(new ActionListener() {
157:                    public void actionPerformed(final ActionEvent event) {
158:                        applyPattern(false);
159:                    }
160:                });
161:                setBorder(BorderFactory.createEmptyBorder(6, 6, 6, 6));
162:            }
163:
164:            /**
165:             * Returns a set of patterns for formatting in the given locale, or {@code null} if none.
166:             *
167:             * @param format for which to get a set of default patterns.
168:             * @todo Need a way to find the format locale.
169:             */
170:            private static synchronized String[] getPatterns(final Format format) {
171:                final Locale locale = Locale.getDefault();
172:                String[][] patterns = (String[][]) PATTERNS.get(locale);
173:                if (patterns == null) {
174:                    patterns = new String[3][];
175:                }
176:                if (format instanceof  NumberFormat) {
177:                    if (patterns[0] == null) {
178:                        patterns[0] = getNumberPatterns(locale);
179:                    }
180:                    return patterns[0];
181:                }
182:                if (format instanceof  DateFormat) {
183:                    if (patterns[1] == null) {
184:                        patterns[1] = getDatePatterns(locale);
185:                    }
186:                    return patterns[1];
187:                }
188:                if (format instanceof  AngleFormat
189:                        || format instanceof  CoordinateFormat) {
190:                    if (patterns[2] == null) {
191:                        patterns[2] = ANGLE_PATTERNS;
192:                    }
193:                    return patterns[2];
194:                }
195:                return null;
196:            }
197:
198:            /**
199:             * Returns a set of patterns for formatting numbers in the given locale.
200:             * Note: this method is costly and should be invoked only once for a given locale.
201:             */
202:            private static String[] getNumberPatterns(final Locale locale) {
203:                final Set patterns = new LinkedHashSet();
204:                int type = 0;
205:                fill: while (true) {
206:                    final int digits;
207:                    final NumberFormat format;
208:                    switch (type++) {
209:                    case 0:
210:                        format = NumberFormat.getInstance(locale);
211:                        digits = -1;
212:                        break;
213:                    case 1:
214:                        format = NumberFormat.getNumberInstance(locale);
215:                        digits = 4;
216:                        break;
217:                    case 2:
218:                        format = NumberFormat.getPercentInstance(locale);
219:                        digits = 2;
220:                        break;
221:                    case 3:
222:                        format = NumberFormat.getCurrencyInstance(locale);
223:                        digits = -1;
224:                        break;
225:                    default:
226:                        break fill;
227:                    }
228:                    if (format instanceof  DecimalFormat) {
229:                        final DecimalFormat decimal = (DecimalFormat) format;
230:                        patterns.add(decimal.toLocalizedPattern());
231:                        for (int i = 0; i <= digits; i++) {
232:                            format.setMinimumFractionDigits(i);
233:                            format.setMaximumFractionDigits(i);
234:                            patterns.add(decimal.toLocalizedPattern());
235:                        }
236:                    }
237:                }
238:                return (String[]) patterns.toArray(new String[patterns.size()]);
239:            }
240:
241:            /**
242:             * Returns a set of patterns for formatting dates in the given locale.
243:             * Note: this method is costly and should be invoked only once for a given locale.
244:             */
245:            private static String[] getDatePatterns(final Locale locale) {
246:                final int[] codes = { SimpleDateFormat.SHORT,
247:                        SimpleDateFormat.MEDIUM, SimpleDateFormat.LONG,
248:                        SimpleDateFormat.FULL };
249:                final Set patterns = new LinkedHashSet();
250:                for (int i = 0; i < codes.length; i++) {
251:                    for (int j = -1; j < codes.length; j++) {
252:                        final DateFormat format;
253:                        if (j < 0) {
254:                            format = DateFormat.getDateInstance(codes[i],
255:                                    locale);
256:                        } else {
257:                            format = DateFormat.getDateTimeInstance(codes[i],
258:                                    codes[j], locale);
259:                        }
260:                        if (format instanceof  SimpleDateFormat) {
261:                            patterns.add(((SimpleDateFormat) format)
262:                                    .toLocalizedPattern());
263:                        }
264:                    }
265:                }
266:                return (String[]) patterns.toArray(new String[patterns.size()]);
267:            }
268:
269:            /**
270:             * Suggest a sample value for the given format, or {@code null} if this
271:             * method has no suggestion.
272:             *
273:             * @param  format The format.
274:             * @return A sample value for the specified format, or {@code null} if none.
275:             */
276:            private static Object suggestSampleValue(final Format format) {
277:                if (format instanceof  NumberFormat) {
278:                    return new Double(39.3); // Could be any random value.
279:                }
280:                if (format instanceof  DateFormat) {
281:                    return new Date(); // Could be any random value.
282:                }
283:                if (format instanceof  AngleFormat) {
284:                    return new Angle(39.3); // Could be any random value.
285:                }
286:                if (format instanceof  CoordinateFormat) {
287:                    final int dimension = ((CoordinateFormat) format)
288:                            .getCoordinateReferenceSystem()
289:                            .getCoordinateSystem().getDimension();
290:                    final GeneralDirectPosition point = new GeneralDirectPosition(
291:                            dimension);
292:                    for (int i = 0; i < dimension; i++) {
293:                        point.setOrdinate(i, (i & 1) == 0 ? 39.3 : 27.9); // Could be any random value.
294:                    }
295:                    return point;
296:                }
297:                return null;
298:            }
299:
300:            /**
301:             * Returns the current format.
302:             */
303:            public Format getFormat() {
304:                return format;
305:            }
306:
307:            /**
308:             * Set the format to configure. The default implementation accept instance of
309:             * {@link DecimalFormat}, {@link SimpleDateFormat} or {@link AngleFormat}. If
310:             * more format class are wanted, methods {@link #getPattern} and {@link #setPattern}
311:             * should be overridden.
312:             *
313:             * @param  format The format to congifure.
314:             * @throws IllegalArgumentException if the format is invalid.
315:             */
316:            public void setFormat(final Format format)
317:                    throws IllegalArgumentException {
318:                final Format old = this .format;
319:                this .format = format;
320:                try {
321:                    update();
322:                } catch (IllegalStateException exception) {
323:                    this .format = old;
324:                    /*
325:                     * The format is not one of recognized type.  Since this format was given in argument
326:                     * (rather then the internal format field), Change the exception type for consistency
327:                     * with the usual specification.
328:                     */
329:                    final IllegalArgumentException e;
330:                    e = new IllegalArgumentException(exception
331:                            .getLocalizedMessage());
332:                    e.initCause(exception);
333:                    throw e;
334:                }
335:                firePropertyChange("format", old, format);
336:            }
337:
338:            /**
339:             * Returns the sample value to format as a "preview" text.
340:             * If no such object is defined, then this method returns {@code null}.
341:             */
342:            public Object getSampleValue() {
343:                return value;
344:            }
345:
346:            /**
347:             * Sets the sample value to format as a "preview" text. The value should
348:             * be an object formatable with {@link #getFormat}.
349:             *
350:             * @param  value The value to format, or {@code null}.
351:             * @throws IllegalArgumentException if the value can't be formatted.
352:             */
353:            public void setSampleValue(final Object value)
354:                    throws IllegalArgumentException {
355:                preview.setText(value != null ? format.format(value) : null);
356:                preview.setForeground(getForeground());
357:                final Object old = this .value;
358:                this .value = value;
359:                firePropertyChange("sampleValue", old, value);
360:            }
361:
362:            /**
363:             * Returns the localized pattern for the {@linkplain #getFormat current format}.
364:             * The default implementation recognize {@link DecimalFormat}, {@link SimpleDateFormat}
365:             * and {@link AngleFormat} instances.
366:             *
367:             * @return The pattern for the current format.
368:             * @throws IllegalStateException is the current format is not one of recognized type.
369:             */
370:            public String getPattern() throws IllegalStateException {
371:                if (format instanceof  DecimalFormat) {
372:                    return ((DecimalFormat) format).toLocalizedPattern();
373:                }
374:                if (format instanceof  SimpleDateFormat) {
375:                    return ((SimpleDateFormat) format).toLocalizedPattern();
376:                }
377:                if (format instanceof  AngleFormat) {
378:                    return ((AngleFormat) format).toPattern();
379:                }
380:                if (format instanceof  CoordinateFormat) {
381:                    final CoordinateFormat format = (CoordinateFormat) this .format;
382:                    for (int i = format.getCoordinateReferenceSystem()
383:                            .getCoordinateSystem().getDimension(); --i >= 0;) {
384:                        final Format sub = format.getFormat(i);
385:                        if (sub instanceof  AngleFormat) {
386:                            return ((AngleFormat) sub).toPattern();
387:                        }
388:                    }
389:                }
390:                throw new IllegalStateException(Utilities
391:                        .getShortClassName(format));
392:            }
393:
394:            /**
395:             * Sets the localized pattern for the {@linkplain #getFormat current format}.
396:             * The default implementation recognize {@link DecimalFormat}, {@link SimpleDateFormat}
397:             * and {@link AngleFormat} instances.
398:             *
399:             * @param  pattern The pattern for the current format.
400:             * @throws IllegalStateException is the current format is not one of recognized type.
401:             * @throws IllegalArgumentException if the specified pattern is invalid.
402:             */
403:            public void setPattern(final String pattern)
404:                    throws IllegalStateException, IllegalArgumentException {
405:                if (format instanceof  DecimalFormat) {
406:                    ((DecimalFormat) format).applyLocalizedPattern(pattern);
407:                } else if (format instanceof  SimpleDateFormat) {
408:                    ((SimpleDateFormat) format).applyLocalizedPattern(pattern);
409:                } else if (format instanceof  AngleFormat) {
410:                    ((AngleFormat) format).applyPattern(pattern);
411:                } else if (format instanceof  CoordinateFormat) {
412:                    ((CoordinateFormat) format).setAnglePattern(pattern);
413:                } else {
414:                    throw new IllegalStateException(Utilities
415:                            .getShortClassName(format));
416:                }
417:                update();
418:            }
419:
420:            /**
421:             * Update the preview text according the current format pattern.
422:             */
423:            final void update() {
424:                choices.setSelectedItem(getPattern());
425:                try {
426:                    preview
427:                            .setText(value != null ? format.format(value)
428:                                    : null);
429:                    preview.setForeground(getForeground());
430:                } catch (IllegalArgumentException exception) {
431:                    /*
432:                     * The value can't be formatted. Replace the
433:                     * value by the format error message.
434:                     */
435:                    preview.setText(exception.getLocalizedMessage());
436:                    preview.setForeground(ERROR_COLOR);
437:                }
438:            }
439:
440:            /**
441:             * Applies the currently selected pattern. If {@code add} is {@code true},
442:             * then the pattern is added to the combo box list.
443:             *
444:             * @param  add {@code true} for adding the pattern to the combo box list.
445:             * @return {@code true} if the pattern is valid.
446:             */
447:            private boolean applyPattern(final boolean add) {
448:                String pattern = choices.getSelectedItem().toString();
449:                if (pattern.trim().length() == 0) {
450:                    update();
451:                    return false;
452:                }
453:                try {
454:                    setPattern(pattern);
455:                } catch (RuntimeException exception) {
456:                    /*
457:                     * The pattern is not valid. Replace the value by an error message.
458:                     */
459:                    preview.setText(exception.getLocalizedMessage());
460:                    preview.setForeground(ERROR_COLOR);
461:                    return false;
462:                }
463:                if (add) {
464:                    final DefaultComboBoxModel model = (DefaultComboBoxModel) choices
465:                            .getModel();
466:                    pattern = choices.getSelectedItem().toString();
467:                    final int index = model.getIndexOf(pattern);
468:                    if (index > 0) {
469:                        model.removeElementAt(index);
470:                    }
471:                    if (index != 0) {
472:                        model.insertElementAt(pattern, 0);
473:                    }
474:                    final int size = model.getSize();
475:                    while (size > HISTORY_SIZE) {
476:                        model.removeElementAt(size - 1);
477:                    }
478:                    if (size != 0) {
479:                        choices.setSelectedIndex(0);
480:                    }
481:                }
482:                return true;
483:            }
484:
485:            /**
486:             * Shows a dialog box requesting input from the user. The dialog box will be
487:             * parented to {@code owner}. If {@code owner} is contained into a
488:             * {@link javax.swing.JDesktopPane}, the dialog box will appears as an internal
489:             * frame. This method can be invoked from any thread (may or may not be the
490:             * <i>Swing</i> thread).
491:             *
492:             * @param  owner The parent component for the dialog box,
493:             *         or {@code null} if there is no parent.
494:             * @param  title The dialog box title.
495:             * @return {@code true} if user pressed the "Ok" button, or
496:             *         {@code false} otherwise (e.g. pressing "Cancel"
497:             *         or closing the dialog box from the title bar).
498:             */
499:            public boolean showDialog(final Component owner, final String title) {
500:                final String old = getPattern();
501:                while (SwingUtilities.showOptionDialog(owner, this , title)) {
502:                    if (applyPattern(true)) {
503:                        return true;
504:                    }
505:                }
506:                setPattern(old);
507:                return false;
508:            }
509:
510:            /**
511:             * Show this component. This method is used mostly in order
512:             * to check the look of this widget from the command line.
513:             */
514:            public static void main(final String[] args) {
515:                final Arguments arguments = new Arguments(args);
516:                Locale.setDefault(arguments.locale);
517:                new FormatChooser(new AngleFormat()).showDialog(null, Utilities
518:                        .getShortName(FormatChooser.class));
519:                System.exit(0);
520:            }
521:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.