Source Code Cross Referenced for SwingEngine.java in  » XML-UI » swixml » org » swixml » 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 » XML UI » swixml » org.swixml 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*--
002:         $Id: SwingEngine.java,v 1.5 2005/06/29 08:02:37 wolfpaulus Exp $
003:
004:         Copyright (C) 2003-2007 Wolf Paulus.
005:         All rights reserved.
006:
007:         Redistribution and use in source and binary forms, with or without
008:         modification, are permitted provided that the following conditions
009:         are met:
010:
011:         1. Redistributions of source code must retain the above copyright
012:         notice, this list of conditions, and the following disclaimer.
013:
014:         2. Redistributions in binary form must reproduce the above copyright
015:         notice, this list of conditions, and the disclaimer that follows
016:         these conditions in the documentation and/or other materials provided
017:         with the distribution.
018:
019:         3. The end-user documentation included with the redistribution,
020:         if any, must include the following acknowledgment:
021:                "This product includes software developed by the
022:                 SWIXML Project (http://www.swixml.org/)."
023:         Alternately, this acknowledgment may appear in the software itself,
024:         if and wherever such third-party acknowledgments normally appear.
025:
026:         4. The name "Swixml" must not be used to endorse or promote products
027:         derived from this software without prior written permission. For
028:         written permission, please contact <info_AT_swixml_DOT_org>
029:
030:         5. Products derived from this software may not be called "Swixml",
031:         nor may "Swixml" appear in their name, without prior written
032:         permission from the Swixml Project Management.
033:
034:         THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
035:         WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
036:         OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
037:         DISCLAIMED.  IN NO EVENT SHALL THE SWIXML PROJECT OR ITS
038:         CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
039:         SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
040:         LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
041:         USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
042:         ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
043:         OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
044:         OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
045:         SUCH DAMAGE.
046:         ====================================================================
047:
048:         This software consists of voluntary contributions made by many
049:         individuals on behalf of the Swixml Project and was originally
050:         created by Wolf Paulus <wolf_AT_swixml_DOT_org>. For more information
051:         on the Swixml Project, please see <http://www.swixml.org/>.
052:         */
053:        package org.swixml;
054:
055:        import org.jdom.Document;
056:        import org.jdom.input.SAXBuilder;
057:
058:        import javax.swing.*;
059:        import java.awt.*;
060:        import java.awt.event.ActionListener;
061:        import java.awt.event.WindowAdapter;
062:        import java.awt.event.WindowEvent;
063:        import java.awt.event.WindowListener;
064:        import java.io.*;
065:        import java.lang.reflect.Field;
066:        import java.lang.reflect.Modifier;
067:        import java.net.URL;
068:        import java.security.AccessControlException;
069:        import java.util.*;
070:        import java.util.List;
071:
072:        /**
073:         * The SwingEngine class is the rendering engine able to convert an XML descriptor into a java.swing UI.
074:         * <p/>
075:         * <img src="doc-files/swixml_1_0.png" ALIGN="center">
076:         * </p>
077:         *
078:         * @author <a href="mailto:wolf@paulus.com">Wolf Paulus</a>
079:         * @version $Revision: 1.5 $
080:         */
081:        public class SwingEngine {
082:            //
083:            //  Static Constants
084:            //
085:            /**
086:             * Mac OSX identifier in System.getProperty(os.name)
087:             */
088:            public static final String MAC_OSX_OS_NAME = "mac os x";
089:
090:            /**
091:             * Mac OSX locale variant to localize strings like quit etc.
092:             */
093:            public static final String MAC_OSX_LOCALE_VARIANT = "mac";
094:
095:            /**
096:             * XML Error
097:             */
098:            private static final String XML_ERROR_MSG = "Invalid SwiXML Descriptor.";
099:            /**
100:             * IO Error Message.
101:             */
102:            private static final String IO_ERROR_MSG = "Resource could not be found ";
103:            /**
104:             * Mapping Error Message.
105:             */
106:            private static final String MAPPING_ERROR_MSG = " could not be mapped to any Object and remained un-initialized.";
107:
108:            //
109:            //  Static Member Variables
110:            //
111:
112:            /**
113:             * Debug / Release Mode
114:             */
115:            public static boolean DEBUG_MODE = false;
116:            /**
117:             * main frame
118:             */
119:            private static Frame appFrame;
120:            /**
121:             * static resource bundle
122:             */
123:            private static String default_resource_bundle_name = null;
124:            /**
125:             * static locale
126:             */
127:            private static Locale default_locale = Locale.getDefault();
128:            /**
129:             * Check is currently running on a Mac
130:             */
131:            private static boolean MAC_OSX = false;
132:            /**
133:             * static Mac OS X Support, set to true to support Mac UI specialties
134:             */
135:            private static boolean MAC_OSX_SUPPORTED = true;
136:
137:            //
138:            //   Static Initializer
139:            //
140:            /** display the swing release version to system out. */
141:            static {
142:                System.out.println("SwixML @version@");
143:                try {
144:                    MAC_OSX = System.getProperty("os.name").toLowerCase()
145:                            .startsWith(SwingEngine.MAC_OSX_OS_NAME);
146:                } catch (Exception e) {
147:                    MAC_OSX = false;
148:                }
149:            }
150:
151:            //
152:            //  Member Variables
153:            //
154:            /**
155:             * Swixml Parser.
156:             */
157:            private Parser parser = new Parser(this );
158:            /**
159:             * Client object hosting the swingengine, alternative to extending the SwinEngine Class
160:             */
161:            private Object client;
162:            /**
163:             * Root Component for the rendered swing UI.
164:             */
165:            private Container root;
166:            /**
167:             * Swing object map, contains only those object that were given an id attribute.
168:             */
169:            private Map<String, Object> idmap = new HashMap<String, Object>();
170:            /**
171:             * Flattened Swing object tree, contains all object, even the ones without an id.
172:             */
173:            private Collection components = null;
174:            /**
175:             * access to taglib to let overwriting class add and remove tags.
176:             */
177:            private Localizer localizer = new Localizer();
178:            //
179:            //  Private Constants
180:            //
181:            /**
182:             * Classload to load resources
183:             */
184:            private final TagLibrary taglib = SwingTagLibrary.getInstance();
185:            /**
186:             * Localizer, setup by parameters found in the xml descriptor.
187:             */
188:            protected ClassLoader cl = this .getClass().getClassLoader();
189:
190:            /**
191:             * Default ctor for a SwingEngine.
192:             */
193:            public SwingEngine() {
194:                this .client = this ;
195:                this .setLocale(SwingEngine.default_locale);
196:                this .getLocalizer().setResourceBundle(
197:                        SwingEngine.default_resource_bundle_name);
198:
199:                try {
200:                    if (SwingEngine.isMacOSXSupported()
201:                            && SwingEngine.isMacOSX()) {
202:                        // Use apple's ScreenMenuBar instead of the MS-Window style
203:                        // application's own menu bar
204:                        System.setProperty("com.apple.macos.useScreenMenuBar",
205:                                "true");
206:                        System
207:                                .setProperty("apple.laf.useScreenMenuBar",
208:                                        "true");
209:
210:                        // Don't let the growbox intrude other widgets
211:                        System.setProperty("apple.awt.showGrowBox", "true");
212:                        System.setProperty(
213:                                "com.apple.mrj.application.growbox.intrudes",
214:                                "false");
215:                    }
216:                } catch (AccessControlException e) {
217:                    // intentionally empty
218:                }
219:            }
220:
221:            /**
222:             * Constructor to be used if the SwingEngine is not extend but used through object composition.
223:             *
224:             * @param client <code>Object</code> owner of this instance
225:             */
226:            public SwingEngine(Object client) {
227:                this ();
228:                this .client = client;
229:            }
230:
231:            /**
232:             * Constructs a new SwingEngine, rendering the provided XML into a javax.swing UI
233:             *
234:             * @param resource <code>String</code>
235:             */
236:            public SwingEngine(final String resource) {
237:                this (SwingEngine.class.getClassLoader(), resource);
238:            }
239:
240:            /**
241:             * Constructs a new SwingEngine, rendering the provided XML into a javax.swing UI
242:             *
243:             * @param resource <code>String</code>
244:             * @deprecated
245:             */
246:            public SwingEngine(ClassLoader cl, final String resource) {
247:                this ();
248:                this .setClassLoader(cl);
249:                Reader reader = null;
250:                try {
251:                    InputStream in = cl.getResourceAsStream(resource);
252:                    if (in == null) {
253:                        throw new IOException(IO_ERROR_MSG + resource);
254:                    }
255:                    reader = new InputStreamReader(in);
256:                    render(reader);
257:                } catch (Exception e) {
258:                    if (SwingEngine.DEBUG_MODE)
259:                        System.err.println(e);
260:                } finally {
261:                    try {
262:                        reader.close();
263:                    } catch (Exception e) {
264:                        // intentionally empty
265:                    }
266:                }
267:            }
268:
269:            /**
270:             * Gets the parsing of the XML started.
271:             *
272:             * @param url <code>URL</code> url pointing to an XML descriptor
273:             * @return <code>Object</code>- instanced swing object tree root
274:             * @throws Exception
275:             */
276:            public Container render(final URL url) throws Exception {
277:                Reader reader = null;
278:                Container obj = null;
279:                try {
280:                    InputStream in = url.openStream();
281:                    if (in == null) {
282:                        throw new IOException(IO_ERROR_MSG + url.toString());
283:                    }
284:                    reader = new InputStreamReader(in);
285:                    obj = render(reader);
286:                } finally {
287:                    try {
288:                        reader.close();
289:                    } catch (Exception ex) {
290:                        // intentionally empty
291:                    }
292:                }
293:                return obj;
294:            }
295:
296:            /**
297:             * Gets the parsing of the XML file started.
298:             *
299:             * @param resource <code>String</code> xml-file path info
300:             * @return <code>Object</code>- instanced swing object tree root
301:             */
302:            public Container render(final String resource) throws Exception {
303:                Reader reader = null;
304:                Container obj = null;
305:                try {
306:                    InputStream in = cl.getResourceAsStream(resource);
307:                    if (in == null) {
308:                        throw new IOException(IO_ERROR_MSG + resource);
309:                    }
310:                    reader = new InputStreamReader(in);
311:                    obj = render(reader);
312:                } finally {
313:                    try {
314:                        reader.close();
315:                    } catch (Exception ex) {
316:                        // intentionally empty
317:                    }
318:                }
319:                return obj;
320:            }
321:
322:            /**
323:             * Gets the parsing of the XML file started.
324:             *
325:             * @param xml_file <code>File</code> xml-file
326:             * @return <code>Object</code>- instanced swing object tree root
327:             */
328:            public Container render(final File xml_file) throws Exception {
329:                if (xml_file == null) {
330:                    throw new IOException();
331:                }
332:                return render(new FileReader(xml_file));
333:            }
334:
335:            /**
336:             * Gets the parsing of the XML file started.
337:             *
338:             * @param xml_reader <code>Reader</code> xml-file path info
339:             * @return <code>Object</code>- instanced swing object tree root
340:             */
341:            public Container render(final Reader xml_reader) throws Exception {
342:                if (xml_reader == null) {
343:                    throw new IOException();
344:                }
345:                try {
346:                    return render(new SAXBuilder().build(xml_reader));
347:                } catch (org.xml.sax.SAXParseException e) {
348:                    System.err.println(e);
349:                } catch (org.jdom.input.JDOMParseException e) {
350:                    System.err.println(e);
351:                }
352:                throw new Exception(SwingEngine.XML_ERROR_MSG);
353:            }
354:
355:            /**
356:             * Gets the parsing of the XML file started.
357:             *
358:             * @param jdoc <code>Document</code> xml gui descritptor
359:             * @return <code>Object</code>- instanced swing object tree root
360:             */
361:            public Container render(final Document jdoc) throws Exception {
362:                idmap.clear();
363:                try {
364:                    root = (Container) parser.parse(jdoc);
365:                } catch (Exception e) {
366:                    if (SwingEngine.DEBUG_MODE)
367:                        System.err.println(e);
368:                    throw (e);
369:                }
370:                // reset components collection
371:                components = null;
372:                // initialize all client fields with UI components by their id
373:                mapMembers(client);
374:                if (Frame.class.isAssignableFrom(root.getClass())) {
375:                    SwingEngine.setAppFrame((Frame) root);
376:                }
377:                return root;
378:            }
379:
380:            /**
381:             * Inserts swing object rendered from an XML document into the given container.
382:             * <p/>
383:             * <pre>
384:             *  Differently to the render methods, insert does NOT consider the root node of the XML document.
385:             * </pre>
386:             * <pre>
387:             *  <b>NOTE:</b><br>insert() does NOT clear() the idmap before rendering.
388:             * Therefore, if this SwingEngine's parser was used before, the idmap still
389:             * contains (key/value) pairs (id, JComponent obj. references).<br>If insert() is NOT
390:             * used to insert in a previously (with this very SwingEngine) rendered UI,
391:             * it is highly recommended to clear the idmap:
392:             * <br>
393:             *  <div>
394:             *    <code>mySwingEngine.getIdMap().clear()</code>
395:             *  </div>
396:             * </pre>
397:             *
398:             * @param url       <code>URL</code> url pointing to an XML descriptor *
399:             * @param container <code>Container</code> target, the swing obj, are added to.
400:             * @throws Exception
401:             */
402:            public void insert(final URL url, final Container container)
403:                    throws Exception {
404:                Reader reader = null;
405:                try {
406:                    InputStream in = url.openStream();
407:                    if (in == null) {
408:                        throw new IOException(IO_ERROR_MSG + url.toString());
409:                    }
410:                    reader = new InputStreamReader(in);
411:                    insert(reader, container);
412:                } finally {
413:                    try {
414:                        reader.close();
415:                    } catch (Exception ex) {
416:                        // intentionally empty
417:                    }
418:                }
419:            }
420:
421:            /**
422:             * Inserts swing objects rendered from an XML reader into the given container.
423:             * <p/>
424:             * <pre>
425:             *  Differently to the render methods, insert does NOT consider the root node of the XML document.
426:             * </pre>
427:             * <pre>
428:             *  <b>NOTE:</b><br>insert() does NOT clear() the idmap before rendering.
429:             * Therefore, if this SwingEngine's parser was used before, the idmap still
430:             * contains (key/value) pairs (id, JComponent obj. references).<br>If insert() is NOT
431:             * used to insert in a previously (with this very SwingEngine) rendered UI, it is highly
432:             * recommended to clear the idmap:
433:             * <br>
434:             *  <div>
435:             *    <code>mySwingEngine.getIdMap().clear()</code>
436:             *  </div>
437:             * </pre>
438:             *
439:             * @param reader    <code>Reader</code> xml-file path info
440:             * @param container <code>Container</code> target, the swing obj, are added to.
441:             * @throws Exception
442:             */
443:            public void insert(final Reader reader, final Container container)
444:                    throws Exception {
445:                if (reader == null) {
446:                    throw new IOException();
447:                }
448:                insert(new SAXBuilder().build(reader), container);
449:            }
450:
451:            /**
452:             * Inserts swing objects rendered from an XML reader into the given container.
453:             * <p/>
454:             * <pre>
455:             *  Differently to the render methods, insert does NOT consider the root node of the XML document.
456:             * </pre>
457:             * <pre>
458:             *  <b>NOTE:</b><br>insert() does NOT clear() the idmap before rendering.
459:             * Therefore, if this SwingEngine's parser was used before, the idmap still
460:             * contains (key/value) pairs (id, JComponent obj. references).<br>
461:             * If insert() is NOT used to insert in a previously (with this very SwingEngine)
462:             * rendered UI, it is highly recommended to clear the idmap:
463:             * <br>
464:             *  <div>
465:             *    <code>mySwingEngine.getIdMap().clear()</code>
466:             *  </div>
467:             * </pre>
468:             *
469:             * @param resource  <code>String</code> xml-file path info
470:             * @param container <code>Container</code> target, the swing obj, are added to.
471:             * @throws Exception
472:             */
473:            public void insert(final String resource, final Container container)
474:                    throws Exception {
475:                Reader reader = null;
476:                try {
477:                    InputStream in = cl.getResourceAsStream(resource);
478:                    if (in == null) {
479:                        throw new IOException(IO_ERROR_MSG + resource);
480:                    }
481:                    reader = new InputStreamReader(in);
482:                    insert(reader, container);
483:                } finally {
484:                    try {
485:                        if (reader != null) {
486:                            reader.close();
487:                        }
488:                    } catch (Exception ex) {
489:                        // intentionally empty
490:                    }
491:                }
492:            }
493:
494:            /**
495:             * Inserts swing objects rendered from an XML document into the given container.
496:             * <p/>
497:             * <pre>
498:             *  Differently to the parse methods, insert does NOT consider the root node of the XML document.
499:             * </pre>
500:             * <pre>
501:             *  <b>NOTE:</b><br>insert() does NOT clear() the idmap before rendering.
502:             * Therefore, if this SwingEngine's parser was used before, the idmap still
503:             * contains (key/value) pairs (id, JComponent obj. references).<br>
504:             * If insert() is NOT
505:             * used to insert in a previously (with this very SwingEngine) rendered UI,
506:             * it is highly recommended to clear the idmap:
507:             * <br>
508:             *  <div>
509:             *    <code>mySwingEngine.getIdMap().clear()</code>
510:             *  </div>
511:             * </pre>
512:             *
513:             * @param jdoc      <code>Document</code> xml-doc path info
514:             * @param container <code>Container</code> target, the swing obj, are added to
515:             * @throws Exception <code>Exception</code> exception thrown by the parser
516:             */
517:            public void insert(final Document jdoc, final Container container)
518:                    throws Exception {
519:                root = container;
520:                try {
521:                    parser.parse(jdoc, container);
522:                } catch (Exception e) {
523:                    if (SwingEngine.DEBUG_MODE)
524:                        System.err.println(e);
525:                    throw (e);
526:                }
527:                // reset components collection
528:                components = null;
529:                // initialize all client fields with UI components by their id
530:                mapMembers(client);
531:            }
532:
533:            /**
534:             * Sets the SwingEngine's global resource bundle name, to be used by all SwingEngine instances. This name can be
535:             * overwritten however for a single instance, if a <code>bundle</code> attribute is places in the root tag of an XML
536:             * descriptor.
537:             *
538:             * @param bundlename <code>String</code> the resource bundle name.
539:             */
540:            public static void setResourceBundleName(String bundlename) {
541:                SwingEngine.default_resource_bundle_name = bundlename;
542:            }
543:
544:            /**
545:             * Sets the SwingEngine's global locale, to be used by all SwingEngine instances. This locale can be overwritten
546:             * however for a single instance, if a <code>locale</code> attribute is places in the root tag of an XML descriptor.
547:             *
548:             * @param locale <code>Locale</code>
549:             */
550:            public static void setDefaultLocale(Locale locale) {
551:                SwingEngine.default_locale = locale;
552:            }
553:
554:            /**
555:             * Sets the SwingEngine's global application frame variable, to be used as a parent for all child dialogs.
556:             *
557:             * @param frame <code>Window</code> the parent for all future dialogs.
558:             */
559:            public static void setAppFrame(Frame frame) {
560:                if (frame != null) {
561:                    if (SwingEngine.appFrame == null) {
562:                        SwingEngine.appFrame = frame;
563:                    }
564:                }
565:            }
566:
567:            /**
568:             * @return <code>Window</code> a parent for all dialogs.
569:             */
570:            public static Frame getAppFrame() {
571:                return SwingEngine.appFrame;
572:            }
573:
574:            /**
575:             * Returns the object which instantiated this SwingEngine.
576:             *
577:             * @return <code>Objecy</code> SwingEngine client object
578:             *         <p/>
579:             *         <p><b>Note:</b><br>
580:             *         This is the object used through introspection the actions and fileds are set.
581:             *         </p>
582:             */
583:            public Object getClient() {
584:                return client;
585:            }
586:
587:            /**
588:             * Returns the root component of the generated Swing UI.
589:             *
590:             * @return <code>Component</code>- the root component of the javax.swing ui
591:             */
592:            public Container getRootComponent() {
593:                return root;
594:            }
595:
596:            /**
597:             * Returns an Iterator for all parsed GUI components.
598:             *
599:             * @return <code>Iterator</code> GUI components itearator
600:             */
601:            public Iterator getAllComponentItertor() {
602:                if (components == null) {
603:                    traverse(root, components = new ArrayList());
604:                }
605:                return components.iterator();
606:            }
607:
608:            /**
609:             * Returns an Iterator for id-ed parsed GUI components.
610:             *
611:             * @return <code>Iterator</code> GUI components itearator
612:             */
613:            public Iterator getIdComponentItertor() {
614:                return idmap.values().iterator();
615:            }
616:
617:            /**
618:             * Returns the id map, containing all id-ed parsed GUI components.
619:             *
620:             * @return <code>Map</code> GUI components map
621:             */
622:            public Map<String, Object> getIdMap() {
623:                return idmap;
624:            }
625:
626:            /**
627:             * Removes all un-displayable compontents from the id map and deletes the components collection (for recreation at the
628:             * next request).
629:             * <p/>
630:             * <pre>
631:             *  A component is made undisplayable either when it is removed from a displayable containment hierarchy or when its
632:             * containment hierarchy is made undisplayable. A containment hierarchy is made undisplayable when its ancestor
633:             * window
634:             * is disposed.
635:             * </pre>
636:             *
637:             * @return <code>int</code> number of removed componentes.
638:             */
639:            public int cleanup() {
640:                List zombies = new ArrayList();
641:                Iterator it = idmap.keySet().iterator();
642:                while (it != null && it.hasNext()) {
643:                    Object key = it.next();
644:                    Object obj = idmap.get(key);
645:                    if (obj instanceof  Component
646:                            && !((Component) obj).isDisplayable()) {
647:                        zombies.add(key);
648:                    }
649:                }
650:                for (int i = 0; i < zombies.size(); i++) {
651:                    idmap.remove(zombies.get(i));
652:                }
653:                components = null;
654:                return zombies.size();
655:            }
656:
657:            /**
658:             * Removes the id from the internal from the id map, to make the given id available for re-use.
659:             *
660:             * @param id <code>String</code> assigned name
661:             */
662:            public void forget(final String id) {
663:                idmap.remove(id);
664:            }
665:
666:            /**
667:             * Returns the UI component with the given name or null.
668:             *
669:             * @param id <code>String</code> assigned name
670:             * @return <code>Component</code>- the GUI component with the given name or null if not found.
671:             */
672:            public Component find(final String id) {
673:                Object obj = idmap.get(id);
674:                if (obj != null
675:                        && !Component.class.isAssignableFrom(obj.getClass())) {
676:                    obj = null;
677:                }
678:                return (Component) obj;
679:            }
680:
681:            /**
682:             * Sets the locale to be used during parsing / String conversion
683:             *
684:             * @param l <code>Locale</code>
685:             */
686:            public void setLocale(Locale l) {
687:                if (SwingEngine.isMacOSXSupported() && SwingEngine.isMacOSX()) {
688:                    l = new Locale(l.getLanguage(), l.getCountry(),
689:                            SwingEngine.MAC_OSX_LOCALE_VARIANT);
690:                }
691:                this .localizer.setLocale(l);
692:            }
693:
694:            /**
695:             * Sets the ResourceBundle to be used during parsing / String conversion
696:             *
697:             * @param bundlename <code>String</code>
698:             */
699:            public void setResourceBundle(String bundlename) {
700:                this .localizer.setResourceBundle(bundlename);
701:            }
702:
703:            /**
704:             * @return <code>Localizer</code>- the Localizer, which is used for localization.
705:             */
706:            public Localizer getLocalizer() {
707:                return localizer;
708:            }
709:
710:            /**
711:             * @return <code>TagLibrary</code>- the Taglibray to insert custom tags.
712:             *         <p/>
713:             *         <pre><b>Note:</b>ConverterLibrary and TagLibray need to be set up before rendering is called.
714:             *                                                                                                                                                                 </pre>
715:             */
716:            public TagLibrary getTaglib() {
717:                return taglib;
718:            }
719:
720:            /**
721:             * Sets a classloader to be used for all <i>getResourse..()</i> and <i> loadClass()</i> calls. If no class loader is
722:             * set, the SwingEngine's loader is used.
723:             *
724:             * @param cl <code>ClassLoader</code>
725:             * @see ClassLoader#loadClass
726:             * @see ClassLoader#getResource
727:             */
728:            public void setClassLoader(ClassLoader cl) {
729:                this .cl = cl;
730:                this .localizer.setClassLoader(cl);
731:            }
732:
733:            /**
734:             * @return <code>ClassLoader</code>- the Classloader used for all <i> getResourse..()</i> and <i>loadClass()</i>
735:             *         calls.
736:             */
737:            public ClassLoader getClassLoader() {
738:                return cl;
739:            }
740:
741:            /**
742:             * Recursively Sets an ActionListener
743:             * <p/>
744:             * <pre>
745:             *  Backtracking algorithm: if al was set for a child component, its not being set for its parent
746:             * </pre>.
747:             *
748:             * @param c  <code>Component</code> start component
749:             * @param al <code>ActionListener</code>
750:             * @return <code>boolean</code> true, if ActionListener was set.
751:             */
752:            public boolean setActionListener(final Component c,
753:                    final ActionListener al) {
754:                boolean b = false;
755:                if (c != null) {
756:                    if (Container.class.isAssignableFrom(c.getClass())) {
757:                        final Component[] s = ((Container) c).getComponents();
758:                        for (Component value : s) {
759:                            b = b | setActionListener(value, al);
760:                        }
761:                    }
762:                    if (!b) {
763:                        if (JMenu.class.isAssignableFrom(c.getClass())) {
764:                            final JMenu m = (JMenu) c;
765:                            final int k = m.getItemCount();
766:                            for (int i = 0; i < k; i++) {
767:                                b = b | setActionListener(m.getItem(i), al);
768:                            }
769:                        } else if (AbstractButton.class.isAssignableFrom(c
770:                                .getClass())) {
771:                            ((AbstractButton) c).addActionListener(al);
772:                            b = true;
773:                        }
774:                    }
775:
776:                }
777:                return b;
778:            }
779:
780:            /**
781:             * Walks the whole tree to add all components into the <code>components<code> collection.
782:             *
783:             * @param c <code> Component</code> recursive start component.
784:             *          <p/>
785:             *          Note:There is another collection available that only tracks
786:             *          those object that were provided with an <em>id</em>attribute, which hold an unique id
787:             *          </p>
788:             * @return <code>Iterator</code> to walk all components, not just the id components.
789:             */
790:            public Iterator getDescendants(final Component c) {
791:                List list = new ArrayList(12);
792:                SwingEngine.traverse(c, list);
793:                return list.iterator();
794:            }
795:
796:            /**
797:             * Introspects the given object's class and initializes its non-transient fields with objects that have been instanced
798:             * during parsing. Mappping happens based on type and field name: the fields name has to be equal to the tag id,
799:             * psecified in the XML descriptor. The fields class has to be assignable (equals or super class..) from the class
800:             * that was used to instance the tag.
801:             *
802:             * @param obj <code>Object</code> target object to be mapped with instanced tags
803:             */
804:            protected void mapMembers(Object obj) {
805:                if (obj != null) {
806:                    mapMembers(obj, obj.getClass());
807:                }
808:            }
809:
810:            private void mapMembers(Object obj, Class cls) {
811:                boolean fullaccess = true;
812:
813:                if (obj != null && cls != null && !Object.class.equals(cls)) {
814:                    Field[] flds = null;
815:                    try {
816:                        flds = cls.getDeclaredFields();
817:                    } catch (AccessControlException e) {
818:                        fullaccess = false; // applet or otherwise restricted environment
819:                        flds = cls.getFields();
820:                    }
821:                    //
822:                    // loops through class' declared fields and try to find a matching widget.
823:                    //
824:                    for (int i = 0; i < flds.length; i++) {
825:                        Object widget = idmap.get(flds[i].getName());
826:                        if (widget != null) {
827:                            // field and object type need to be compatible and field must not be declared Transient
828:                            if (flds[i].getType().isAssignableFrom(
829:                                    widget.getClass())
830:                                    && !Modifier.isTransient(flds[i]
831:                                            .getModifiers())) {
832:                                try {
833:
834:                                    boolean accessible = flds[i].isAccessible();
835:                                    flds[i].setAccessible(true);
836:                                    flds[i].set(obj, widget);
837:                                    flds[i].setAccessible(accessible);
838:                                } catch (AccessControlException e) {
839:                                    try {
840:                                        fullaccess = false;
841:                                        flds[i].set(obj, widget);
842:                                    } catch (IllegalAccessException e1) {
843:                                    }
844:
845:                                } catch (IllegalArgumentException e) {
846:                                    // intentionally empty
847:                                } catch (IllegalAccessException e) {
848:                                    // intentionally empty
849:                                }
850:                            }
851:                        }
852:
853:                        //
854:                        //  If an intended mapping didn't work out the objects member would remain un-initialized.
855:                        //  To prevent this, we try to instantiate with a default ctor.
856:                        //
857:                        if (flds[i] == null) {
858:                            if (!SwingEngine.DEBUG_MODE) {
859:                                try {
860:                                    flds[i].set(obj, flds[i].getType()
861:                                            .newInstance());
862:                                } catch (IllegalArgumentException e) {
863:                                    // intentionally empty
864:                                } catch (IllegalAccessException e) {
865:                                    // intentionally empty
866:                                } catch (InstantiationException e) {
867:                                    // intentionally empty
868:                                }
869:                            } else { // SwingEngine.DEBUG_MODE)
870:                                System.err.println(flds[i].getType() + " : "
871:                                        + flds[i].getName()
872:                                        + SwingEngine.MAPPING_ERROR_MSG);
873:                            }
874:                        }
875:                    }
876:
877:                    // Since getDeclaredFields() only works on the class itself, not the super class,
878:                    // we need to make this recursive down to the object.class
879:                    if (fullaccess) {
880:                        // only if we have access to the declared fields do we need to visit the whole tree.
881:                        mapMembers(obj, cls.getSuperclass());
882:                    }
883:                }
884:            }
885:
886:            /**
887:             * Walks the whole tree to add all components into the <code>components<code> collection.
888:             *
889:             * @param c          <code>Component</code> recursive start component.
890:             * @param collection <code>Collection</code> target collection.
891:             *                   <p/>
892:             *                   Note:There is another collection available that only tracks
893:             *                   those object that were provided with an <em>id</em>attribute, which hold an unique id
894:             *                   </p>
895:             */
896:            protected static void traverse(final Component c,
897:                    Collection collection) {
898:                if (c != null) {
899:                    collection.add(c);
900:                    if (c instanceof  JMenu) {
901:                        final JMenu m = (JMenu) c;
902:                        final int k = m.getItemCount();
903:                        for (int i = 0; i < k; i++) {
904:                            traverse(m.getItem(i), collection);
905:                        }
906:                    } else if (c instanceof  Container) {
907:                        final Component[] s = ((Container) c).getComponents();
908:                        for (Component value : s) {
909:                            traverse(value, collection);
910:                        }
911:                    }
912:                }
913:            }
914:
915:            /**
916:             * Enables or disables support of Mac OS X GUIs
917:             *
918:             * @param osx <code>boolean</code>
919:             */
920:            public static void setMacOSXSuport(boolean osx) {
921:                SwingEngine.MAC_OSX_SUPPORTED = osx;
922:            }
923:
924:            /**
925:             * Indicates state of Mac OS X support (default is true = ON).
926:             *
927:             * @return <code>boolean</code>- indicating MacOS support is enabled
928:             */
929:            public static boolean isMacOSXSupported() {
930:                return SwingEngine.MAC_OSX_SUPPORTED;
931:            }
932:
933:            /**
934:             * Indicates if currently running on Mac OS X
935:             *
936:             * @return <code>boolean</code>- indicating if currently running on a MAC
937:             */
938:            public static boolean isMacOSX() {
939:                return SwingEngine.MAC_OSX;
940:            }
941:
942:            /**
943:             * Displays the GUI during a RAD session. If the root component is neither a JFrame nor a JDialog, the a JFrame is
944:             * instantiated and the root is added into the new frames contentpane.
945:             */
946:            public void test() {
947:                WindowListener wl = new WindowAdapter() {
948:                    public void windowClosing(WindowEvent e) {
949:                        super .windowClosing(e);
950:                        System.exit(0);
951:                    }
952:                };
953:                if (root != null) {
954:                    if (JFrame.class.isAssignableFrom(root.getClass())
955:                            || JDialog.class.isAssignableFrom(root.getClass())) {
956:                        ((Window) root).addWindowListener(wl);
957:                        root.setVisible(true);
958:                    } else {
959:                        JFrame jf = new JFrame("SwiXml Test");
960:                        jf.getContentPane().add(root);
961:                        jf.pack();
962:                        jf.addWindowListener(wl);
963:                        jf.setVisible(true);
964:                    }
965:                }
966:            }
967:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.