Source Code Cross Referenced for About.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:        // User interface
020:        import java.awt.Dimension;
021:        import java.awt.Component;
022:        import java.awt.EventQueue;
023:        import java.awt.GridLayout;
024:        import java.awt.BorderLayout;
025:        import java.awt.GridBagLayout;
026:        import java.awt.GridBagConstraints;
027:        import javax.swing.event.ListDataListener;
028:        import javax.swing.tree.DefaultMutableTreeNode;
029:        import javax.swing.tree.MutableTreeNode;
030:        import javax.swing.AbstractListModel;
031:        import javax.swing.BorderFactory;
032:        import javax.swing.JOptionPane;
033:        import javax.swing.JTabbedPane;
034:        import javax.swing.JScrollPane;
035:        import javax.swing.JComponent;
036:        import javax.swing.ImageIcon;
037:        import javax.swing.JPanel;
038:        import javax.swing.JLabel;
039:        import javax.swing.JList;
040:        import javax.swing.JTree;
041:        import javax.swing.Icon;
042:
043:        // Input/output
044:        import java.net.URL;
045:        import java.io.IOException;
046:        import java.io.InputStream;
047:        import javax.imageio.spi.IIORegistry;
048:        import javax.imageio.spi.ImageReaderSpi;
049:        import javax.imageio.spi.ImageWriterSpi;
050:        import javax.imageio.spi.ImageReaderWriterSpi;
051:
052:        // Manifest
053:        import java.util.jar.Manifest;
054:        import java.util.jar.Attributes;
055:
056:        // Formatting
057:        import java.text.DateFormat;
058:        import java.text.FieldPosition;
059:        import java.text.ParseException;
060:        import java.text.SimpleDateFormat;
061:
062:        // Miscellaneous
063:        import java.util.Map;
064:        import java.util.Date;
065:        import java.util.Locale;
066:        import java.util.Arrays;
067:        import java.util.TreeMap;
068:        import java.util.Iterator;
069:
070:        // Java Advanced Imaging
071:        import javax.media.jai.JAI;
072:
073:        // Geotools dependencies
074:        import org.geotools.util.logging.Logging;
075:        import org.geotools.resources.XArray;
076:        import org.geotools.resources.Arguments;
077:        import org.geotools.resources.SwingUtilities;
078:        import org.geotools.resources.i18n.Vocabulary;
079:        import org.geotools.resources.i18n.VocabularyKeys;
080:        import org.geotools.gui.swing.image.RegisteredOperationBrowser;
081:
082:        /**
083:         * An "About" dialog box. This dialog box contains the application's title and some
084:         * system informations (Java and OS version, free memory, image readers and writers, running
085:         * threads, etc.). The application version can be fetched from a {@link Manifest} object,
086:         * usually build from the {@code META-INF/Manifest.mf} file. This manifest should contains
087:         * entries for {@code Implementation-Title}, {@code Implementation-Version} and
088:         * {@code Implementation-Vendor} values, as suggested in the
089:         * <A HREF="http://java.sun.com/docs/books/tutorial/jar/basics/manifest.html#versioning">Java
090:         * tutorial</A>.
091:         * In addition to the above-cited standard entries, the {@code About} class understand also
092:         * an optional {@code Implementation-Date} entry. This entry can contains the product date
093:         * in the <code>"yyyy-MM-dd HH:mm:ss"</code> patter. If presents, this date will be localized
094:         * according user's locale and appended to the version number.
095:         *
096:         * <p>&nbsp;</p>
097:         * <p align="center"><img src="doc-files/About.png"></p>
098:         * <p>&nbsp;</p>
099:         *
100:         * @since 2.0
101:         * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/widgets-swing/src/main/java/org/geotools/gui/swing/About.java $
102:         * @version $Id: About.java 27848 2007-11-12 13:10:32Z desruisseaux $
103:         * @author Martin Desruisseaux
104:         */
105:        public class About extends JPanel {
106:            /**
107:             * The amount of bytes in one "unit of memory" to be displayed.
108:             */
109:            private static final float HEAP_SIZE_UNIT = (1024f * 1024f);
110:
111:            /**
112:             * The entry for timestamp in the manifest file.
113:             */
114:            private static final String TIMESTAMP = "Implementation-Date";
115:
116:            /**
117:             * Thread qui aura la charge de faire des mises à jour en arrière-plan.
118:             * Ce champ sera {@code null} s'il n'y en a pas.
119:             */
120:            private final ThreadList updater;
121:
122:            /**
123:             * The localized resources to use.
124:             */
125:            private final Vocabulary resources;
126:
127:            /**
128:             * Construct a new dialog box with the Geotools's logo.
129:             */
130:            public About() {
131:                this ("org/geotools/resources/logo/Geotools.png", About.class,
132:                        null);
133:            }
134:
135:            /**
136:             * Constructs a new dialog box for the specified application class. This constructor
137:             * uses the class loader for loading the manifest file. It also use the class package
138:             * to find the right entry into the manifest.
139:             *
140:             * @param logo        The application's logo. It may be a {@link JComponent}, an
141:             *                    {@link Icon} object or an resource path (i.e. a file to be
142:             *                    fetch in the classpath) as a {@link String}.
143:             * @param application The application's class. Application name will be fetch
144:             *                    from the manifest file ({@code META-INF/Manifest.mf}).
145:             * @param tasks       Group of running threads, or {@code null} if there is none.
146:             */
147:            public About(final Object logo, final Class application,
148:                    final ThreadGroup tasks) {
149:                this (logo, getAttributes(application), application
150:                        .getClassLoader(), tasks);
151:            }
152:
153:            /**
154:             * Constructs a new dialog box from the specified manifest attributes.
155:             *
156:             * @param logo        The application's logo. It may be a {@link JComponent}, an
157:             *                    {@link Icon} object or an resource path (i.e. a file to be
158:             *                    fetch in the classpath) as a {@link String}.
159:             * @param attributes  The manifest attributes containing application name and version number.
160:             * @param tasks       Group of running threads, or {@code null} if there is none.
161:             */
162:            public About(final Object logo, final Attributes attributes,
163:                    final ThreadGroup tasks) {
164:                this (logo, attributes, null, tasks);
165:            }
166:
167:            /**
168:             * Constructs a new dialog box.
169:             *
170:             * @param logo        The application's logo. It may be a {@link JComponent}, an
171:             *                    {@link Icon} object or an resource path (i.e. a file to be
172:             *                    fetch in the classpath) as a {@link String}.
173:             * @param attributes  The manifest attributes containing application name and version number.
174:             * @param loader      The application's class loader.
175:             * @param tasks       Group of running threads, or {@code null} if there is none.
176:             */
177:            private About(final Object logo, final Attributes attributes,
178:                    ClassLoader loader, final ThreadGroup tasks) {
179:                super (new GridBagLayout());
180:                final Locale locale = getDefaultLocale();
181:                resources = Vocabulary.getResources(locale);
182:                if (loader == null) {
183:                    loader = getClass().getClassLoader();
184:                    // TODO: it would be nice to fetch the caller's class loader instead
185:                }
186:                /*
187:                 * Get the free memory before any futher work.
188:                 */
189:                final Runtime system = Runtime.getRuntime();
190:                system.gc();
191:                final float freeMemory = system.freeMemory() / HEAP_SIZE_UNIT;
192:                final float totalMemory = system.totalMemory() / HEAP_SIZE_UNIT;
193:                /*
194:                 * Get application's name, version and vendor from the manifest attributes.
195:                 * If an implementation date is specified, append it to the version string.
196:                 */
197:                String application = attributes
198:                        .getValue(Attributes.Name.IMPLEMENTATION_TITLE);
199:                String version = attributes
200:                        .getValue(Attributes.Name.IMPLEMENTATION_VERSION);
201:                String vendor = attributes
202:                        .getValue(Attributes.Name.IMPLEMENTATION_VENDOR);
203:                try {
204:                    final String dateString = attributes.getValue(TIMESTAMP);
205:                    if (dateString != null) {
206:                        final Date date = getDateFormat().parse(dateString);
207:                        final DateFormat format = DateFormat
208:                                .getDateInstance(DateFormat.LONG);
209:                        if (version != null && version.trim().length() != 0) {
210:                            StringBuffer buffer = new StringBuffer(version);
211:                            buffer.append(" (");
212:                            buffer = format.format(date, buffer,
213:                                    new FieldPosition(0));
214:                            buffer.append(')');
215:                            version = buffer.toString();
216:                        } else {
217:                            version = format.format(date);
218:                        }
219:                    }
220:                } catch (ParseException exception) {
221:                    /*
222:                     * The implementation date can't be parsed. This is not a show-stopper;
223:                     * the "About" dialog box will just not includes the implementation date.
224:                     */
225:                    Logging.unexpectedException("org.geotools.gui.swing",
226:                            About.class, "<init>", exception);
227:                }
228:                /*
229:                 * If the user supplied a logo, load it and display it in the dialog's upper part (NORTH).
230:                 * The tabbed pane will be added below the logo, in the dialog's central part (CENTER).
231:                 */
232:                final GridBagConstraints gc = new GridBagConstraints();
233:                if (logo != null) {
234:                    final JComponent title;
235:                    if (logo instanceof  JComponent) {
236:                        title = (JComponent) logo;
237:                    } else if (logo instanceof  Icon) {
238:                        title = new JLabel((Icon) logo);
239:                    } else {
240:                        final String text = String.valueOf(logo);
241:                        final URL url = loader.getResource(text);
242:                        if (url == null) {
243:                            final JLabel label = new JLabel(text);
244:                            label.setHorizontalAlignment(JLabel.CENTER);
245:                            label.setBorder(BorderFactory
246:                                    .createEmptyBorder(6/*top*/, 6/*left*/,
247:                                            6/*bottom*/, 6/*right*/));
248:                            title = label;
249:                        } else {
250:                            title = new JLabel(new ImageIcon(url));
251:                        }
252:                    }
253:                    title.setBorder(BorderFactory.createCompoundBorder(
254:                            BorderFactory.createEmptyBorder(0/*top*/,
255:                                    0/*left*/, 6/*bottom*/, 0/*right*/),
256:                            BorderFactory.createCompoundBorder(BorderFactory
257:                                    .createLoweredBevelBorder(), title
258:                                    .getBorder())));
259:                    gc.gridx = 0;
260:                    gc.gridy = 0;
261:                    gc.weightx = 1;
262:                    gc.insets.top = 9;
263:                    add(title, gc);
264:                }
265:                final JTabbedPane tabs = new JTabbedPane();
266:                final JLabel totalMemoryLabel = new JLabel(resources.getString(
267:                        VocabularyKeys.MEMORY_HEAP_SIZE_$1, new Float(
268:                                totalMemory)));
269:                final JLabel percentUsedLabel = new JLabel(resources.getString(
270:                        VocabularyKeys.MEMORY_HEAP_USAGE_$1, new Float(1
271:                                - freeMemory / totalMemory)));
272:                gc.gridx = 0;
273:                gc.gridy = 1;
274:                gc.weightx = 1;
275:                gc.weighty = 1;
276:                gc.fill = gc.BOTH;
277:                add(tabs, gc);
278:                /*
279:                 * MAIN TAB (Application name and version informations)
280:                 */
281:                if (true) {
282:                    final JPanel pane = new JPanel(new GridBagLayout());
283:                    final GridBagConstraints c = new GridBagConstraints();
284:                    c.gridx = 0;
285:                    c.weightx = 1;
286:                    c.gridy = 0;
287:                    c.insets.top = 12;
288:                    pane.add(new JLabel(application), c);
289:                    c.gridy++;
290:                    c.insets.top = 0;
291:                    pane.add(new JLabel(resources.getString(
292:                            VocabularyKeys.VERSION_$1, version)), c);
293:                    c.gridy++;
294:                    pane.add(new JLabel(vendor), c);
295:                    c.gridy++;
296:                    c.insets.top = 6;
297:                    pane.add(new JLabel(resources.getString(
298:                            VocabularyKeys.JAVA_VERSION_$1, System
299:                                    .getProperty("java.version"))), c);
300:                    c.gridy++;
301:                    c.insets.top = 0;
302:                    pane.add(new JLabel(resources.getString(
303:                            VocabularyKeys.JAVA_VENDOR_$1, System
304:                                    .getProperty("java.vendor"))), c);
305:                    c.gridy++;
306:                    c.insets.top = 6;
307:                    pane.add(new JLabel(resources.getString(
308:                            VocabularyKeys.OS_NAME_$1, System
309:                                    .getProperty("os.name"))), c);
310:                    c.gridy++;
311:                    c.insets.top = 0;
312:                    pane.add(new JLabel(resources.getString(
313:                            VocabularyKeys.OS_VERSION_$2, System
314:                                    .getProperty("os.version"), System
315:                                    .getProperty("os.arch"))), c);
316:                    c.gridy++;
317:                    c.insets.top = 12;
318:                    pane.add(new JLabel(resources.getString(
319:                            VocabularyKeys.TILE_CACHE_CAPACITY_$1, new Float(
320:                                    JAI.getDefaultInstance().getTileCache()
321:                                            .getMemoryCapacity()
322:                                            / HEAP_SIZE_UNIT))), c);
323:                    c.gridy++;
324:                    c.insets.top = 0;
325:                    pane.add(totalMemoryLabel, c);
326:                    c.gridy++;
327:                    c.insets.bottom = 12;
328:                    pane.add(percentUsedLabel, c);
329:                    tabs.addTab(resources.getString(VocabularyKeys.SYSTEM),
330:                            pane);
331:                }
332:                /*
333:                 * RUNNING TASKS TAB
334:                 */
335:                if (tasks != null) {
336:                    updater = new ThreadList(tasks, totalMemoryLabel,
337:                            percentUsedLabel, resources);
338:                    final JPanel pane = new JPanel(new BorderLayout());
339:                    final JList list = new JList(updater);
340:                    pane.add(new JLabel(resources
341:                            .getString(VocabularyKeys.RUNNING_TASKS)),
342:                            BorderLayout.NORTH);
343:                    pane.add(new JScrollPane(list), BorderLayout.CENTER);
344:                    pane.setBorder(BorderFactory.createEmptyBorder(9, 9, 9, 9));
345:                    tabs
346:                            .addTab(resources.getString(VocabularyKeys.TASKS),
347:                                    pane);
348:                } else {
349:                    updater = null;
350:                }
351:                /*
352:                 * IMAGE ENCODERS/DECODERS TAB
353:                 */
354:                if (true) {
355:                    final StringBuffer buffer = new StringBuffer();
356:                    final Map mimes = new TreeMap();
357:                    boolean writer = false;
358:                    do {
359:                        final int titleKey;
360:                        final Class category;
361:                        if (writer) {
362:                            titleKey = VocabularyKeys.ENCODERS;
363:                            category = ImageWriterSpi.class;
364:                        } else {
365:                            titleKey = VocabularyKeys.DECODERS;
366:                            category = ImageReaderSpi.class;
367:                        }
368:                        String title = resources.getString(titleKey);
369:                        Iterator it = IIORegistry.getDefaultInstance()
370:                                .getServiceProviders(category, true);
371:                        while (it.hasNext()) {
372:                            final ImageReaderWriterSpi spi = (ImageReaderWriterSpi) it
373:                                    .next();
374:                            final String name = spi.getDescription(locale);
375:                            final String[] mimeTypes = spi.getMIMETypes();
376:                            patchMimes(mimeTypes);
377:                            for (int i = 0; i < mimeTypes.length; i++) {
378:                                final String mimeType = mimeTypes[i];
379:                                DefaultMutableTreeNode child = (DefaultMutableTreeNode) mimes
380:                                        .get(mimeType);
381:                                if (child == null) {
382:                                    child = new DefaultMutableTreeNode(mimeType);
383:                                    mimes.put(mimeType, child);
384:                                }
385:                                child.add(new DefaultMutableTreeNode(name,
386:                                        false));
387:                            }
388:                            if (title != null && mimeTypes.length != 0) {
389:                                if (buffer.length() != 0) {
390:                                    buffer.append(" / ");
391:                                }
392:                                buffer.append(title);
393:                                title = null;
394:                            }
395:                        }
396:                    } while ((writer = !writer) == true);
397:                    final String title = buffer.toString();
398:                    final DefaultMutableTreeNode root = new DefaultMutableTreeNode(
399:                            title);
400:                    for (final Iterator it = mimes.values().iterator(); it
401:                            .hasNext();) {
402:                        root.add((DefaultMutableTreeNode) it.next());
403:                    }
404:                    JComponent tree = new JTree(root);
405:                    tree.setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 0));
406:                    tree = new JScrollPane(tree);
407:                    tabs.addTab(resources.getString(VocabularyKeys.IMAGES),
408:                            setup(tree));
409:                }
410:                /*
411:                 * JAI OPERATIONS TAB
412:                 */
413:                if (true) {
414:                    final JComponent tree = new RegisteredOperationBrowser();
415:                    tabs.addTab(resources.getString(VocabularyKeys.OPERATIONS),
416:                            setup(tree));
417:                }
418:            }
419:
420:            /**
421:             * Setup the border for the specified component.
422:             */
423:            private static JComponent setup(JComponent component) {
424:                component.setBorder(BorderFactory.createCompoundBorder(
425:                        BorderFactory.createEmptyBorder(3, 3, 3, 3), component
426:                                .getBorder()));
427:                component.setPreferredSize(new Dimension(200, 200));
428:                return component;
429:            }
430:
431:            /**
432:             * Patch the mime type, replacing "" by "(raw)" for JAI I/O codec.
433:             */
434:            private static void patchMimes(String[] mimes) {
435:                for (int i = 0; i < mimes.length; i++) {
436:                    String name = mimes[i].trim();
437:                    if (name.length() == 0) {
438:                        name = "(raw)";
439:                    }
440:                    mimes[i] = name;
441:                }
442:            }
443:
444:            /**
445:             * Returns attribute for the specified class.
446:             */
447:            private static Attributes getAttributes(final Class classe) {
448:                InputStream stream = classe.getClassLoader()
449:                        .getResourceAsStream("META-INF/Manifest.mf");
450:                if (stream != null)
451:                    try {
452:                        final Manifest manifest = new Manifest(stream);
453:                        stream.close();
454:                        String name = classe.getName().replace('.', '/');
455:                        int index;
456:                        while ((index = name.lastIndexOf('/')) >= 0) {
457:                            final Attributes attributes = manifest
458:                                    .getAttributes(name.substring(0, index + 1));
459:                            if (attributes != null)
460:                                return attributes;
461:                            name = name.substring(0, index);
462:                        }
463:                        return manifest.getMainAttributes();
464:                    } catch (IOException e) {
465:                        Logging.unexpectedException("org.geotools.gui.swing",
466:                                About.class, "getAttributes", e);
467:                    }
468:                // Use empty manifest attributes.
469:                return new Attributes();
470:            }
471:
472:            /**
473:             * Returns a neutral date format for timestamp.
474:             */
475:            private static DateFormat getDateFormat() {
476:                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
477:                        Locale.CANADA);
478:            }
479:
480:            /**
481:             * Modèle représentant la liste des processus actif dans un {@link ThreadGroup}.
482:             * Cette liste se mettre automatiquement à jour de façon périodique.
483:             *
484:             * @version $Id: About.java 27848 2007-11-12 13:10:32Z desruisseaux $
485:             * @author Martin Desruisseaux
486:             */
487:            private static final class ThreadList extends AbstractListModel
488:                    implements  Runnable {
489:                /**
490:                 * Processus qui met à jour {@code ThreadList}, ou {@code null} s'il n'y en a pas.
491:                 * On peut tuer le processus actif en donnant la valeur {@code null} à cette variable.
492:                 */
493:                public transient Thread worker;
494:
495:                /**
496:                 * Liste des processus en cours.
497:                 */
498:                private final ThreadGroup tasks;
499:
500:                /**
501:                 * Liste des noms des processus en cours. Cette liste sera mises à jour périodiquement.
502:                 */
503:                private String[] names = new String[0];
504:
505:                /**
506:                 * Texte dans lequel écrire la mémoire totale réservée.
507:                 */
508:                private final JLabel totalMemory;
509:
510:                /**
511:                 * Texte dans lequel écrire le pourcentage de mémoire utilisée.
512:                 */
513:                private final JLabel percentUsed;
514:
515:                /**
516:                 * The localized resources to use.
517:                 */
518:                private final Vocabulary resources;
519:
520:                /**
521:                 * Construit une liste des processus actifs dans le groupe {@code tasks} spécifié.
522:                 */
523:                public ThreadList(final ThreadGroup tasks,
524:                        final JLabel totalMemory, final JLabel percentUsed,
525:                        final Vocabulary resources) {
526:                    this .tasks = tasks;
527:                    this .totalMemory = totalMemory;
528:                    this .percentUsed = percentUsed;
529:                    this .resources = resources;
530:                }
531:
532:                /**
533:                 * Retourne le nombre d'éléments dans la liste.
534:                 */
535:                public int getSize() { // NO synchronized here
536:                    return names.length;
537:                }
538:
539:                /**
540:                 * Retourne un des éléments de la liste.
541:                 */
542:                public Object getElementAt(final int index) { // NO synchronized here
543:                    return names[index];
544:                }
545:
546:                /**
547:                 * Ajoute un objet à la liste des objets intéressés
548:                 * à être informé des changements apportés à la liste.
549:                 */
550:                public synchronized void addListDataListener(
551:                        final ListDataListener listener) {
552:                    super .addListDataListener(listener);
553:                }
554:
555:                /**
556:                 * Démarre le thread.
557:                 */
558:                public synchronized void start() {
559:                    if (worker == null) {
560:                        worker = new Thread(this , resources
561:                                .getString(VocabularyKeys.ABOUT));
562:                        worker.setPriority(Thread.MIN_PRIORITY);
563:                        worker.setDaemon(true);
564:                        worker.start();
565:                    }
566:                }
567:
568:                /**
569:                 * Met à jour le contenu de la liste à interval régulier.
570:                 * Cette méthode est exécutée dans une boucle jusqu'à ce
571:                 * qu'elle soit interrompue en donnant la valeur nulle à
572:                 * {@link #tasks}.
573:                 */
574:                public synchronized void run() {
575:                    String oldTotalMemory = null;
576:                    String oldPercentUsed = null;
577:                    while (worker == Thread.currentThread()
578:                            && listenerList.getListenerCount() != 0) {
579:                        final Runtime system = Runtime.getRuntime();
580:                        final float freeMemoryN = system.freeMemory()
581:                                / HEAP_SIZE_UNIT;
582:                        final float totalMemoryN = system.totalMemory()
583:                                / HEAP_SIZE_UNIT;
584:                        String totalMemoryText = resources.getString(
585:                                VocabularyKeys.MEMORY_HEAP_SIZE_$1, new Float(
586:                                        totalMemoryN));
587:                        String percentUsedText = resources.getString(
588:                                VocabularyKeys.MEMORY_HEAP_USAGE_$1, new Float(
589:                                        1 - freeMemoryN / totalMemoryN));
590:
591:                        Thread[] threadArray = new Thread[tasks.activeCount()];
592:                        String[] threadNames = new String[tasks
593:                                .enumerate(threadArray)];
594:                        int c = 0;
595:                        for (int i = 0; i < threadNames.length; i++) {
596:                            if (threadArray[i] != worker) {
597:                                threadNames[c++] = threadArray[i].getName();
598:                            }
599:                        }
600:                        threadNames = (String[]) XArray.resize(threadNames, c);
601:
602:                        if (Arrays.equals(names, threadNames)) {
603:                            threadNames = null;
604:                        }
605:                        if (totalMemoryText.equals(oldTotalMemory)) {
606:                            totalMemoryText = null;
607:                        } else {
608:                            oldTotalMemory = totalMemoryText;
609:                        }
610:                        if (percentUsedText.equals(oldPercentUsed)) {
611:                            percentUsedText = null;
612:                        } else {
613:                            oldPercentUsed = percentUsedText;
614:                        }
615:                        if (threadNames != null || totalMemoryText != null
616:                                || percentUsedText != null) {
617:                            final String[] names = threadNames;
618:                            final String totalMemory = totalMemoryText;
619:                            final String percentUsed = percentUsedText;
620:                            EventQueue.invokeLater(new Runnable() {
621:                                public void run() {
622:                                    update(names, totalMemory, percentUsed);
623:                                }
624:                            });
625:                        }
626:                        try {
627:                            wait(4000);
628:                        } catch (InterruptedException exception) {
629:                            // Quelqu'un a réveillé ce thread. Retourne au travail.
630:                        }
631:                    }
632:                    worker = null;
633:                }
634:
635:                /**
636:                 * Met à jour le contenu de la liste. Cette méthode
637:                 * est appelée périodiquement dans le thread de Swing.
638:                 */
639:                private synchronized void update(final String[] newNames,
640:                        final String totalMemory, final String percentUsed) {
641:                    if (newNames != null) {
642:                        final int count = Math.max(names.length,
643:                                newNames.length);
644:                        names = newNames;
645:                        fireContentsChanged(this , 0, count - 1);
646:                    }
647:                    if (totalMemory != null)
648:                        this .totalMemory.setText(totalMemory);
649:                    if (percentUsed != null)
650:                        this .percentUsed.setText(percentUsed);
651:                }
652:            }
653:
654:            /**
655:             * Popups the dialog box and wait for the user. This method
656:             * always invoke {@link #start} before showing the dialog,
657:             * and {@link #stop} after disposing it.
658:             */
659:            public void showDialog(final Component owner) {
660:                try {
661:                    start();
662:                    SwingUtilities.showMessageDialog(owner, this , resources
663:                            .getMenuLabel(VocabularyKeys.ABOUT),
664:                            JOptionPane.PLAIN_MESSAGE);
665:                } finally {
666:                    stop();
667:                }
668:            }
669:
670:            /**
671:             * Start a daemon thread updating dialog box information. Updated information include
672:             * available memory and the list of running tasks. <strong>You <u>must</u> invoke the
673:             * {@link #stop} method after {@code start()}</strong> (typically in a {@code try..finally}
674:             * construct) in order to free resources. {@code stop()} is not automatically
675:             * invoked by the garbage collector.
676:             */
677:            protected void start() {
678:                final ThreadList updater = this .updater;
679:                if (updater != null) {
680:                    updater.start();
681:                }
682:            }
683:
684:            /**
685:             * Free any resources used by this dialog box.  <strong>This method must be invoked
686:             * after {@link #start}</strong> in order to free resources. {@code stop()} is
687:             * not automatically invoked by the garbage collector.
688:             */
689:            protected void stop() {
690:                final ThreadList updater = this .updater;
691:                if (updater != null) {
692:                    updater.worker = null; // Stop the thread.
693:                }
694:                // Le thread avait une référence indirecte vers 'this' via 'ListDataListener'
695:            }
696:
697:            /**
698:             * Convenience method for setting the {@code Implementation-Date}
699:             * attributes to the current date.
700:             *
701:             * @param attributes Attributes in which setting the compilation date.
702:             */
703:            public static void touch(final Attributes attributes) {
704:                attributes.putValue(TIMESTAMP, getDateFormat().format(
705:                        new Date()));
706:            }
707:
708:            /**
709:             * Display the default "About" dialog box. This method is usefull
710:             * for testing the widget appareance and for checking system informations.
711:             *
712:             * @param args the command line arguments
713:             */
714:            public static void main(final String[] args) {
715:                final Arguments arguments = new Arguments(args);
716:                Locale.setDefault(arguments.locale);
717:                new About().showDialog(null);
718:                System.exit(0);
719:            }
720:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.