Source Code Cross Referenced for Application.java in  » Web-Framework » ThinWire » thinwire » ui » 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 » Web Framework » ThinWire » thinwire.ui 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:        #IFNDEF ALT_LICENSE
003:                                   ThinWire(R) RIA Ajax Framework
004:                         Copyright (C) 2003-2007 Custom Credit Systems
005:
006:          This library is free software; you can redistribute it and/or modify it under
007:          the terms of the GNU Lesser General Public License as published by the Free
008:          Software Foundation; either version 2.1 of the License, or (at your option) any
009:          later version.
010:
011:          This library is distributed in the hope that it will be useful, but WITHOUT ANY
012:          WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
013:          PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
014:
015:          You should have received a copy of the GNU Lesser General Public License along
016:          with this library; if not, write to the Free Software Foundation, Inc., 59
017:          Temple Place, Suite 330, Boston, MA 02111-1307 USA
018:
019:          Users who would rather have a commercial license, warranty or support should
020:          contact the following company who invented, built and supports the technology:
021:          
022:                        Custom Credit Systems, Richardson, TX 75081, USA.
023:           	            email: info@thinwire.com    ph: +1 (888) 644-6405
024:         	                        http://www.thinwire.com
025:        #ENDIF
026:         [ v1.2_RC2 ] 
027:         */
028:        package thinwire.ui;
029:
030:        import java.io.*;
031:        import java.lang.ref.WeakReference;
032:        import java.net.MalformedURLException;
033:        import java.net.URL;
034:        import java.net.URLConnection;
035:        import java.util.ArrayList;
036:        import java.util.Collections;
037:        import java.util.HashMap;
038:        import java.util.Map;
039:        import java.util.List;
040:        import java.util.Properties;
041:        import java.util.WeakHashMap;
042:        import java.util.EventListener;
043:        import java.util.logging.Level;
044:        import java.util.logging.Logger;
045:        import java.util.zip.*;
046:
047:        import thinwire.render.Renderer;
048:        import thinwire.ui.event.ActionEvent;
049:        import thinwire.ui.event.ActionListener;
050:        import thinwire.ui.event.DropListener;
051:        import thinwire.ui.event.ExceptionEvent;
052:        import thinwire.ui.event.ExceptionListener;
053:        import thinwire.ui.event.ItemChangeListener;
054:        import thinwire.ui.event.KeyPressListener;
055:        import thinwire.ui.event.PropertyChangeEvent;
056:        import thinwire.ui.event.PropertyChangeListener;
057:        import thinwire.ui.style.*;
058:        import thinwire.util.XOD;
059:
060:        /**
061:         * The Application class represents an instance of a ThinWire application.  Methods in this class are
062:         *  those that directly affect the system and it's environment.
063:         * @author Joshua J. Gertzen
064:         */
065:        public abstract class Application {
066:            private static final Logger log = Logger
067:                    .getLogger(Application.class.getName());
068:            private static final String DEFAULT_STYLE_SHEET = "class:///"
069:                    + Application.class.getName()
070:                    + "/resources/CorporateStyle.zip";
071:
072:            private static final Map<String, String> versionInfo;
073:            private static final Map<Class<? extends Component>, Style> defaultStyleMap;
074:
075:            static {
076:                Properties props = new Properties();
077:                Map<String, String> vi = new HashMap<String, String>();
078:
079:                try {
080:                    props
081:                            .load(Application.class
082:                                    .getResourceAsStream("resources/versionInfo.properties"));
083:
084:                    for (Map.Entry<Object, Object> e : props.entrySet()) {
085:                        String key = e.getKey().toString();
086:                        key = key.substring(key.indexOf('.') + 1);
087:                        vi.put(key, e.getValue().toString());
088:                    }
089:
090:                    versionInfo = Collections.unmodifiableMap(vi);
091:                    XOD xod = new XOD();
092:                    xod.execute(DEFAULT_STYLE_SHEET + "/Style.xml");
093:                    defaultStyleMap = buildStyleMap(xod);
094:                } catch (IOException e) {
095:                    throw new RuntimeException(e);
096:                }
097:            }
098:
099:            private Map<Local, Object> appLocal = new WeakHashMap<Local, Object>();
100:
101:            public static class Local<T> {
102:                public void set(T value) {
103:                    Map<Local, Object> map = Application.current().appLocal;
104:
105:                    synchronized (map) {
106:                        map.put(this , value);
107:                    }
108:                }
109:
110:                public T get() {
111:                    Map<Local, Object> map = Application.current().appLocal;
112:
113:                    synchronized (map) {
114:                        T value = (T) map.get(this );
115:                        if (value == null && !map.containsKey(this ))
116:                            map.put(this , value = initialValue());
117:                        return value;
118:                    }
119:                }
120:
121:                protected T initialValue() {
122:                    return null;
123:                }
124:            }
125:
126:            /**
127:             * Returns the current version info details for the platform.
128:             * The returned Map is read-only and contains the following keys:
129:             * companyName
130:             * companyAddress1
131:             * companyAddress2
132:             * companyCity
133:             * companyState
134:             * companyZip
135:             * companyPhone
136:             * companyWebsite
137:             * productDescription
138:             * productVersion
139:             * internalName
140:             * legalCopyright
141:             * originalFilename
142:             * @return the current version info details for the platform.
143:             */
144:            public static Map<String, String> getPlatformVersionInfo() {
145:                return versionInfo;
146:            }
147:
148:            /**
149:             * Displays a version detail dialog.
150:             * @param args
151:             */
152:            public static void main(String[] args) throws Exception {
153:                StringBuilder sb = new StringBuilder();
154:                BufferedReader r = new BufferedReader(
155:                        new InputStreamReader(
156:                                Application.class
157:                                        .getResourceAsStream("resources/licenseHeader.txt")));
158:                String line = r.readLine();
159:
160:                while (line != null) {
161:                    sb.append(line).append('\n');
162:                    line = r.readLine();
163:                }
164:
165:                sb
166:                        .append("\nContents of the Application.getPlatformVersionInfo() map:\n\n");
167:
168:                for (Map.Entry<String, String> e : getPlatformVersionInfo()
169:                        .entrySet()) {
170:                    sb.append(e.getKey()).append("=").append(e.getValue())
171:                            .append('\n');
172:                }
173:
174:                final java.awt.Frame frame = new java.awt.Frame(
175:                        "ThinWire(R) RIA Ajax Framework v"
176:                                + getPlatformVersionInfo()
177:                                        .get("productVersion"));
178:                final java.awt.TextArea ta = new java.awt.TextArea(sb
179:                        .toString());
180:                ta.setEditable(false);
181:                frame.add(ta);
182:                frame.setSize(640, 480);
183:                frame.setVisible(true);
184:                frame.addWindowListener(new java.awt.event.WindowAdapter() {
185:                    public void windowClosing(java.awt.event.WindowEvent ev) {
186:                        frame.dispose();
187:                    }
188:                });
189:            }
190:
191:            /**
192:             * @return the current instance of the application, or null if called from a thread other than the UI thread.
193:             */
194:            public static Application current() {
195:                return thinwire.render.web.WebApplication.current();
196:            }
197:
198:            static boolean validateURL(String url) {
199:                if (url != null && url.trim().length() > 0) {
200:                    int index = url.indexOf(".zip");
201:                    if (index > 0 && index + 5 < url.length())
202:                        url = url.substring(0, index + 4);
203:
204:                    if (url.startsWith("class:///")) {
205:                        return true;
206:                    } else if (url.indexOf("://") >= 0
207:                            && !url.startsWith("file:///")) {
208:                        try {
209:                            new URL(url);
210:                            return true;
211:                        } catch (MalformedURLException e) {
212:                            return false;
213:                        }
214:                    } else {
215:                        Application app = Application.current();
216:                        if (url.startsWith("file:///"))
217:                            url = url.substring(7);
218:                        File file = app == null ? new File(url) : app
219:                                .getRelativeFile(url);
220:                        return file.exists();
221:                    }
222:                } else {
223:                    return false;
224:                }
225:            }
226:
227:            /**
228:             * Returns an InputStream representing the specified resource.
229:             * The following URL's are supported:
230:             * <ul>
231:             *  <li>Any valid resource filename. If Application.current() returns non-null,
232:             *   which is the typical scenario, then relative paths are interpreted as 
233:             *   relative to the application folder. {@link #getRelativeFile}</li>
234:             *  <li>class:///com.mypackage.MyClass/resource.ext</li>
235:             *  <li>http://www.mycompany.com/resource.ext</li>
236:             * </ul>
237:             * 
238:             * @return an InputStream representing the specified resource or null if the resource was not found.
239:             */
240:            public static InputStream getResourceAsStream(String uri) {
241:                InputStream is = null;
242:
243:                if (uri != null && uri.trim().length() > 0) {
244:                    try {
245:                        String innerFile = null;
246:                        int index = uri.indexOf(".zip");
247:
248:                        if (index > 0 && index + 5 < uri.length()) {
249:                            innerFile = uri.substring(index + 5);
250:                            uri = uri.substring(0, index + 4);
251:                        }
252:
253:                        //"class:///thinwire.ui.layout.SplitLayout/resources/Image.png"
254:                        if (uri.startsWith("class:///")) {
255:                            int endIndex = uri.indexOf('/', 9);
256:                            String className = uri.substring(9, endIndex);
257:                            String resource = uri.substring(endIndex + 1);
258:                            Class clazz = Class.forName(className);
259:                            is = clazz.getResourceAsStream(resource);
260:                        } else if (uri.indexOf("://") >= 0
261:                                && !uri.startsWith("file:///")) {
262:                            URL remoteImageURL = new URL(uri);
263:                            URLConnection remoteImageConnection = remoteImageURL
264:                                    .openConnection();
265:                            is = remoteImageConnection.getInputStream();
266:                        } else {
267:                            Application app = Application.current();
268:                            if (uri.startsWith("file:///"))
269:                                uri = uri.substring(7);
270:                            File file = app == null ? new File(uri) : app
271:                                    .getRelativeFile(uri);
272:                            if (file.exists())
273:                                is = new FileInputStream(file);
274:                        }
275:
276:                        if (is != null) {
277:                            is = new BufferedInputStream(is);
278:
279:                            if (innerFile != null) {
280:                                innerFile = innerFile.replace('\\', '/')
281:                                        .toLowerCase();
282:                                ZipInputStream zip = new ZipInputStream(is);
283:                                is = null;
284:                                ZipEntry entry;
285:
286:                                while ((entry = zip.getNextEntry()) != null) {
287:                                    if (!entry.isDirectory()
288:                                            && entry.getName().toLowerCase()
289:                                                    .equals(innerFile)) {
290:                                        byte[] bytes = new byte[(int) entry
291:                                                .getSize()];
292:                                        int pos = 0, cnt;
293:
294:                                        while ((cnt = zip.read(bytes, pos,
295:                                                bytes.length - pos)) > 0) {
296:                                            pos += cnt;
297:                                        }
298:
299:                                        is = new ByteArrayInputStream(bytes);
300:                                        break;
301:                                    }
302:
303:                                    zip.closeEntry();
304:                                }
305:
306:                                zip.close();
307:                            }
308:                        }
309:                    } catch (Exception e) {
310:                        if (e instanceof  RuntimeException)
311:                            throw (RuntimeException) e;
312:                        throw new RuntimeException(e);
313:                    }
314:                }
315:
316:                return is;
317:            }
318:
319:            public static byte[] getResourceBytes(String uri) {
320:                ByteArrayOutputStream baos = new ByteArrayOutputStream();
321:                writeResourceToStream(uri, baos);
322:                return baos.toByteArray();
323:            }
324:
325:            public static void writeResourceToStream(String uri, OutputStream os) {
326:                if (os == null)
327:                    throw new IllegalArgumentException("os == null");
328:                InputStream is = getResourceAsStream(uri);
329:                if (is == null)
330:                    throw new IllegalArgumentException(
331:                            "Content for URI was not found:" + uri);
332:                byte[] bytes = new byte[128];
333:                int size;
334:
335:                try {
336:                    while ((size = is.read(bytes)) != -1)
337:                        os.write(bytes, 0, size);
338:
339:                    is.close();
340:                } catch (IOException e) {
341:                    throw new RuntimeException(e);
342:                }
343:            }
344:
345:            public static Style getDefaultStyle(Class<? extends Component> clazz) {
346:                if (clazz == null)
347:                    throw new IllegalArgumentException("clazz == null");
348:                Map<Class<? extends Component>, Style> map = current() != null ? current().compTypeToStyle
349:                        : defaultStyleMap;
350:
351:                Style style = map.get(clazz);
352:
353:                if (style == null) {
354:                    List<Class<? extends Component>> lst = new ArrayList<Class<? extends Component>>();
355:                    lst.add(clazz);
356:
357:                    do {
358:                        Class<? extends Component> findClazz = lst.remove(0);
359:                        style = map.get(findClazz);
360:
361:                        if (style == null) {
362:                            Class sc = findClazz.getSuperclass();
363:                            if (Component.class.isAssignableFrom(sc))
364:                                lst.add(sc);
365:
366:                            for (Class i : findClazz.getInterfaces()) {
367:                                if (Component.class.isAssignableFrom(i))
368:                                    lst.add(i);
369:                            }
370:                        } else {
371:                            break;
372:                        }
373:                    } while (lst.size() > 0);
374:
375:                    if (style == null)
376:                        style = map.get(null);
377:                    map.put(clazz, style);
378:                }
379:
380:                return style;
381:            }
382:
383:            private static Map<Class<? extends Component>, Style> buildStyleMap(
384:                    XOD props) {
385:                Map<Class<? extends Component>, Style> styleMap = new HashMap<Class<? extends Component>, Style>();
386:
387:                for (Map.Entry<String, Object> e : props.getObjectMap()
388:                        .entrySet()) {
389:                    String name = e.getKey();
390:                    Object value = e.getValue();
391:
392:                    if (value instanceof  Style) {
393:                        if (name.startsWith("default")) {
394:                            if (name.equals("default"))
395:                                styleMap.put(null, (Style) value);
396:                        } else if (name.matches(".*?[A-Z].*?")) {
397:                            if (Character.isUpperCase(name.charAt(0))
398:                                    && name.indexOf('.') == -1)
399:                                name = "thinwire.ui." + name;
400:
401:                            try {
402:                                Class clazz = Class.forName(name);
403:                                if (clazz.getMethod("getStyle") != null)
404:                                    styleMap.put(
405:                                            (Class<? extends Component>) clazz,
406:                                            (Style) value);
407:                            } catch (Exception ex) { /*purposely fall through*/
408:                            }
409:                        }
410:                    } else if (!(value instanceof  Color)) {
411:                        throw new UnsupportedOperationException(
412:                                "Unsupported object type in style sheet:"
413:                                        + value.getClass());
414:                    }
415:                }
416:
417:                return styleMap;
418:            }
419:
420:            private List<ExceptionListener> exceptionListeners;
421:            private Map<Class, EventListenerImpl> globalListeners;
422:            private WeakReference<Component> priorFocus;
423:            private Frame frame;
424:
425:            private Map<String, Color> systemColors;
426:            private Map<String, String> systemImages;
427:            private Map<Class<? extends Component>, Style> compTypeToStyle;
428:
429:            protected Application() {
430:                exceptionListeners = new ArrayList<ExceptionListener>();
431:            }
432:
433:            <T extends EventListener> EventListenerImpl<T> getGlobalListenerSet(
434:                    Class<T> type, boolean createIfNull) {
435:                if (globalListeners == null) {
436:                    if (createIfNull) {
437:                        globalListeners = new HashMap<Class, EventListenerImpl>();
438:                    } else {
439:                        return null;
440:                    }
441:                }
442:
443:                EventListenerImpl<T> set = globalListeners.get(type);
444:                if (set == null && createIfNull)
445:                    globalListeners.put(type, set = new EventListenerImpl<T>(
446:                            null, type));
447:                return set;
448:            }
449:
450:            /**
451:             * Adds a <code>PropertyChangeListener</code> that will be notified when the specified property of any new component changes. To
452:             * further clarify, a global property change listener will receive an event notification for any component that is created after
453:             * this global property change listener is added, for which the specified property changes.  Therefore, establishing a global
454:             * property change listener is the same as invoking the {@link Component#addPropertyChangeListener(String, PropertyChangeListener)}
455:             * method on every component after it's creation. 
456:             * <p>
457:             * As a general rule, you should avoid using this feature because it can cause a large volume of events to be generated. This is
458:             * especially true if you listen to a frequently updated property, such as <code>PROPERTY_TEXT</code>. However, there are
459:             * cases where this can be quite useful. One such case is when you use the 'userObject' property to store a boolean state that
460:             * indicates whether a value is required for the component. In such a case, you can establish a global property change listener
461:             * for 'userObject' and then based on the property being set to <code>true</code> you could update the background color so it
462:             * is apparent to the user that a value is required.
463:             * </p>
464:             * <b>Example:</b>
465:             * 
466:             * <pre>
467:             * Component.addGlobalPropertyChangeListener(Component.PROPERTY_USER_OBJECT, new PropertyChangeListener() {
468:             *     public void propertyChange(PropertyChangeEvent pce) {
469:             *         Component comp = (Component) pce.getSource();
470:             * 
471:             *         if (comp.getUserObject() == Boolean.TRUE) {
472:             *             comp.getStyle().getBackground().setColor(Color.PALEGOLDENROD);
473:             *         } else {
474:             *             comp.getStyle().getBackground().setColor(null); //restore the default background color
475:             *         }
476:             *     }
477:             * });
478:             * 
479:             * TextField tf = new TextField();
480:             * tf.setUserObject(Boolean.TRUE); //Causes background color to be set to Color.PALEGOLDENROD
481:             * tf.setUserObject(Boolean.FALSE); //Causes background color to be set to the default.
482:             * </pre>
483:             * 
484:             * @param propertyName the name of the property that the listener will receive change events for.
485:             * @param listener the listener that will receive <code>PropertyChangeEvent</code> objects upon the property of any new component changing.
486:             * @throws IllegalArgumentException if <code>listener</code> or <code>propertyName</code> is null or if
487:             *         <code>propertyName</code> is an empty string.
488:             * @see Component#addPropertyChangeListener(String, PropertyChangeListener)
489:             * @see thinwire.ui.event.PropertyChangeListener
490:             * @see thinwire.ui.event.PropertyChangeEvent
491:             */
492:            public void addGlobalPropertyChangeListener(String propertyName,
493:                    PropertyChangeListener listener) {
494:                EventListenerImpl<PropertyChangeListener> set = getGlobalListenerSet(
495:                        PropertyChangeListener.class, true);
496:                set.addListener(propertyName, listener);
497:            }
498:
499:            /**
500:             * Adds a <code>PropertyChangeListener</code> that will be notified when any of the specified properties of
501:             * any new component changes. This method is equivalent to calling
502:             * {@link #addGlobalPropertyChangeListener(String, PropertyChangeListener)} once for each property you want to listen to.
503:             * @param propertyNames a string array of property names that the listener will receive change events for.
504:             * @param listener the listerner that will receive <code>PropertyChangeEvent</code> objects anytime one of the specified
505:             *        propertyNames of any new component change.
506:             * @throws IllegalArgumentException if <code>listener</code>, <code>propertyNames</code> or any property name is the array is null or if
507:             *         any property name is an empty string.
508:             * @see #addGlobalPropertyChangeListener(String, PropertyChangeListener)
509:             * @see Component#addPropertyChangeListener(String[], PropertyChangeListener)
510:             * @see thinwire.ui.event.PropertyChangeListener
511:             * @see thinwire.ui.event.PropertyChangeEvent
512:             */
513:            public void addGlobalPropertyChangeListener(String[] propertyNames,
514:                    PropertyChangeListener listener) {
515:                EventListenerImpl<PropertyChangeListener> set = getGlobalListenerSet(
516:                        PropertyChangeListener.class, true);
517:                set.addListener(propertyNames, listener);
518:            }
519:
520:            /**
521:             * Removes the <code>PropertyChangeListener</code> from the list of global listeners that are added to all 
522:             * new <code>Component</code>'s.  To further clarify, removing a global property change listener will NOT
523:             * remove the <code>listener</code> from <code>Component</code>'s that have already been created.
524:             * @param listener the listener to remove from the notification list.
525:             * @throws IllegalArgumentException if <code>listener</code> is null.
526:             * @see thinwire.ui.event.PropertyChangeListener
527:             */
528:            public void removeGlobalPropertyChangeListener(
529:                    PropertyChangeListener listener) {
530:                EventListenerImpl<PropertyChangeListener> set = getGlobalListenerSet(
531:                        PropertyChangeListener.class, true);
532:                set.removeListener(listener);
533:            }
534:
535:            /**
536:             * Adds a <code>ActionListener</code> that will be notified when the specified action occurs on any new component. To
537:             * further clarify, a global action listener will receive an event notification for any component that is created after
538:             * this global action listener is added, on which the specified action occurs.  Therefore, establishing a global
539:             * action listener is the same as invoking the {@link Component#addActionListener(String, ActionListener)}
540:             * method on every component after it's creation. 
541:             * @param action the action to specficially be notified of.
542:             * @param listener the event listener that will receive notification.
543:             */
544:            public void addGlobalActionListener(String action,
545:                    ActionListener listener) {
546:                EventListenerImpl<ActionListener> set = getGlobalListenerSet(
547:                        ActionListener.class, true);
548:                set.addListener(action, listener);
549:            }
550:
551:            /**
552:             * Adds a <code>ActionListener</code> that will be notified when any of the specified actions occur on
553:             * any new component. This method is equivalent to calling
554:             * {@link #addGlobalActionListener(String, ActionListener)} once for each action you want to receive notification for.
555:             * @param actions the actions to specficially be notified of.
556:             * @param listener the event listener that will receive notifications.
557:             */
558:            public void addGlobalActionListener(String[] actions,
559:                    ActionListener listener) {
560:                EventListenerImpl<ActionListener> set = getGlobalListenerSet(
561:                        ActionListener.class, true);
562:                set.addListener(actions, listener);
563:            }
564:
565:            /**
566:             * Unregister an <code>ActionListener</code> from all action event notifications from any component.
567:             * @param listener the listener that should no longer receive action event notifications.
568:             */
569:            public void removeGlobalActionListener(ActionListener listener) {
570:                EventListenerImpl<ActionListener> set = getGlobalListenerSet(
571:                        ActionListener.class, true);
572:                set.removeListener(listener);
573:            }
574:
575:            public void addGlobalDropListener(Component dragSource,
576:                    DropListener listener) {
577:                EventListenerImpl<DropListener> set = getGlobalListenerSet(
578:                        DropListener.class, true);
579:                set.addListener(dragSource, listener);
580:            }
581:
582:            public void addGlobalDropListener(Component[] dragSources,
583:                    DropListener listener) {
584:                EventListenerImpl<DropListener> set = getGlobalListenerSet(
585:                        DropListener.class, true);
586:                set.addListener(dragSources, listener);
587:            }
588:
589:            public void removeGlobalDropListener(DropListener listener) {
590:                EventListenerImpl<DropListener> set = getGlobalListenerSet(
591:                        DropListener.class, true);
592:                set.removeListener(listener);
593:            }
594:
595:            public void addGlobalKeyPressListener(String keyPressCombo,
596:                    KeyPressListener listener) {
597:                EventListenerImpl<KeyPressListener> set = getGlobalListenerSet(
598:                        KeyPressListener.class, true);
599:                set.addListener(keyPressCombo, listener);
600:            }
601:
602:            public void addGlobalKeyPressListener(String[] keyPressCombos,
603:                    KeyPressListener listener) {
604:                EventListenerImpl<KeyPressListener> set = getGlobalListenerSet(
605:                        KeyPressListener.class, true);
606:                set.addListener(keyPressCombos, listener);
607:            }
608:
609:            public void removeGlobalKeyPressListener(KeyPressListener listener) {
610:                EventListenerImpl<KeyPressListener> set = getGlobalListenerSet(
611:                        KeyPressListener.class, true);
612:                set.removeListener(listener);
613:            }
614:
615:            public void addGlobalItemChangeListener(ItemChangeListener listener) {
616:                EventListenerImpl<ItemChangeListener> set = getGlobalListenerSet(
617:                        ItemChangeListener.class, true);
618:                set.addListener(listener);
619:            }
620:
621:            public void removeGlobalItemChangeListener(
622:                    ItemChangeListener listener) {
623:                EventListenerImpl<ItemChangeListener> set = getGlobalListenerSet(
624:                        ItemChangeListener.class, true);
625:                set.removeListener(listener);
626:            }
627:
628:            /**
629:             * 
630:             * @param listener
631:             */
632:            public void addExceptionListener(ExceptionListener listener) {
633:                exceptionListeners.add(listener);
634:            }
635:
636:            /**
637:             * 
638:             * @param listener
639:             */
640:            public void removeExceptionListener(ExceptionListener listener) {
641:                exceptionListeners.remove(listener);
642:            }
643:
644:            /**
645:             * 
646:             * @param source
647:             * @param exception
648:             */
649:            public void reportException(Object source, Throwable exception) {
650:                ExceptionEvent ee = new ExceptionEvent(source, exception);
651:
652:                for (ExceptionListener el : exceptionListeners
653:                        .toArray(new ExceptionListener[exceptionListeners
654:                                .size()])) {
655:                    el.exceptionOccurred(ee);
656:                    if (ee.isStopPropagation())
657:                        break;
658:                }
659:
660:                if (!ee.isSuppressLogging())
661:                    log.log(Level.SEVERE, null, exception);
662:
663:                if (!ee.isCanceled()) {
664:                    final int msgSize = 300;
665:                    final int gap = 5;
666:                    final Dialog d = new Dialog("System Exception");
667:                    String image = "WARNING";
668:                    Image img = null;
669:
670:                    if (getRelativeFile(image).exists()) {
671:                        img = new Image(image);
672:                        img.setBounds(gap, gap, 40, 40);
673:                        d.getChildren().add(img);
674:                    }
675:
676:                    final TextArea taUserMessage = new TextArea(ee
677:                            .getDefaultMessage());
678:                    taUserMessage.setBounds(img == null ? gap : img.getX()
679:                            + img.getWidth() + gap, gap, msgSize, 60);
680:                    taUserMessage.setEnabled(false);
681:                    d.getChildren().add(taUserMessage);
682:
683:                    final Button bDetail = new Button("Show Details >>");
684:                    bDetail.setSize(90, 25);
685:                    bDetail.setPosition(taUserMessage.getX()
686:                            + taUserMessage.getWidth() - bDetail.getWidth(),
687:                            taUserMessage.getY() + taUserMessage.getHeight()
688:                                    + gap);
689:                    d.getChildren().add(bDetail);
690:
691:                    final TextArea taDetail = new TextArea(ee
692:                            .getStackTraceText());
693:
694:                    final Button bOk = new Button();
695:                    bOk.setBounds(bDetail.getX() - gap - bDetail.getWidth(),
696:                            bDetail.getY(), bDetail.getWidth(), bDetail
697:                                    .getHeight());
698:                    bOk.setText("OK");
699:                    d.getChildren().add(bOk);
700:                    bOk.addActionListener(Button.ACTION_CLICK,
701:                            new ActionListener() {
702:                                public void actionPerformed(ActionEvent ev) {
703:                                    d.setVisible(false);
704:                                }
705:                            });
706:
707:                    taDetail.setBounds(taUserMessage.getX(), bOk.getY()
708:                            + bOk.getHeight() + gap, msgSize * 2, msgSize);
709:                    taDetail.setVisible(false);
710:                    d.getChildren().add(taDetail);
711:
712:                    int x = (getFrame().getInnerWidth() / 2)
713:                            - ((d.getWidth() + msgSize) / 2);
714:                    int y = (getFrame().getInnerHeight() / 2)
715:                            - ((d.getHeight() + msgSize) / 2);
716:                    if (x < 0)
717:                        x = 0;
718:                    if (y < 0)
719:                        y = 0;
720:                    d.setPosition(x, y);
721:
722:                    final int normalWidth = 6 + taUserMessage.getX()
723:                            + taUserMessage.getWidth() + gap;
724:                    final int normalHeight = 25 + bDetail.getY()
725:                            + bDetail.getHeight() + gap;
726:                    d.setSize(normalWidth, normalHeight);
727:                    final int[] detailSize = new int[4];
728:                    detailSize[0] = normalWidth + msgSize;
729:                    detailSize[1] = normalHeight + msgSize + gap;
730:                    detailSize[2] = taDetail.getWidth();
731:                    detailSize[3] = taDetail.getHeight();
732:
733:                    final PropertyChangeListener dialogSizePCL = new PropertyChangeListener() {
734:                        public void propertyChange(PropertyChangeEvent pce) {
735:                            int diff = ((Integer) pce.getNewValue())
736:                                    - ((Integer) pce.getOldValue());
737:
738:                            if (pce.getPropertyName().equals(
739:                                    Dialog.PROPERTY_WIDTH)) {
740:                                diff = taDetail.getWidth() + diff;
741:                                if (diff < 10)
742:                                    diff = 10;
743:                                taDetail.setWidth(diff);
744:                            } else {
745:                                diff = taDetail.getHeight() + diff;
746:                                if (diff < 10)
747:                                    diff = 10;
748:                                taDetail.setHeight(diff);
749:                            }
750:                        }
751:                    };
752:
753:                    bDetail.addActionListener(Button.ACTION_CLICK,
754:                            new ActionListener() {
755:                                public void actionPerformed(ActionEvent ev) {
756:                                    if (bDetail.getText().equals(
757:                                            "Show Details >>")) {
758:                                        bDetail.setText("<< Hide Details");
759:                                        d.setResizeAllowed(true);
760:                                        d.setSize(detailSize[0], detailSize[1]);
761:                                        taDetail.setSize(detailSize[2],
762:                                                detailSize[3]);
763:                                        taDetail.setVisible(true);
764:                                        d
765:                                                .addPropertyChangeListener(
766:                                                        new String[] {
767:                                                                Dialog.PROPERTY_WIDTH,
768:                                                                Dialog.PROPERTY_HEIGHT },
769:                                                        dialogSizePCL);
770:                                    } else if (bDetail.getText().equals(
771:                                            "<< Hide Details")) {
772:                                        d
773:                                                .removePropertyChangeListener(dialogSizePCL);
774:                                        bDetail.setText("Show Details >>");
775:                                        d.setResizeAllowed(false);
776:                                        d.setSize(normalWidth, normalHeight);
777:                                        taDetail.setVisible(false);
778:                                    }
779:                                }
780:                            });
781:
782:                    d.setVisible(true);
783:                }
784:            }
785:
786:            /**
787:             * Gets the <code>Frame</code> that represents the primary application window.
788:             * @return the <code>Frame</code> that represents the primary application window.
789:             */
790:            public Frame getFrame() {
791:                if (frame == null)
792:                    frame = new Frame();
793:                return frame;
794:            }
795:
796:            /**
797:             * Returns the <code>Component</code> that previously had focus in the Application. The <code>Component</code> that
798:             * previously had focus is the last <code>Component</code> in ANY window that held the focus. This is different from the
799:             * behavior of the focus property in which their is one <code>Component</code> with focus PER window.
800:             * @return the <code>Component</code> that previously had focus in the Application, or null if no <code>Component</code> has
801:             *         had prior focus.
802:             * @see Component#isFocus()
803:             * @see Component#setFocus(boolean)
804:             */
805:            public Component getPriorFocus() {
806:                return priorFocus.get();
807:            }
808:
809:            protected void loadStyleSheet(String styleSheet) {
810:                XOD props = new XOD();
811:                String sheet = styleSheet == null ? DEFAULT_STYLE_SHEET
812:                        : styleSheet;
813:                sheet = getSystemFile(sheet);
814:                if (!sheet.endsWith(".xml"))
815:                    sheet += "/Style.xml";
816:                props.execute(sheet);
817:                compTypeToStyle = buildStyleMap(props);
818:                systemColors = new HashMap<String, Color>();
819:                systemImages = new HashMap<String, String>();
820:
821:                for (Map.Entry<String, Object> e : props.getObjectMap()
822:                        .entrySet()) {
823:                    String name = e.getKey();
824:                    Object value = e.getValue();
825:
826:                    if (value instanceof  Color) {
827:                        Color color = Color.valueOf(name); //Just verify that the specified systemColor is valid;
828:                        if (!color.isSystemColor())
829:                            throw new UnsupportedOperationException(
830:                                    "You can only override system colors in the style sheet: "
831:                                            + name);
832:                        systemColors.put(color.toString(), (Color) value);
833:                    } else if (!(value instanceof  Style)) {
834:                        throw new UnsupportedOperationException(
835:                                "Unsupported object type in style sheet:"
836:                                        + value.getClass());
837:                    }
838:                }
839:
840:                for (Color c : Color.values()) {
841:                    if (c.isSystemColor()) {
842:                        String name = c.toString();
843:                        if (systemColors.get(name) == null)
844:                            systemColors.put(name, c);
845:                    }
846:                }
847:
848:                for (Map.Entry<String, String> e : props.getPropertyMap()
849:                        .entrySet()) {
850:                    String key = e.getKey();
851:
852:                    if (key.startsWith("image.")) {
853:                        key = key.substring(6).replace('.', '_').toUpperCase();
854:                        systemImages.put(key, e.getValue());
855:                    }
856:                }
857:            }
858:
859:            protected String getSystemFile(String value) {
860:                if (!value.matches("^\\w{3,}://.*")) {
861:                    if (value != null && !value.matches("^\\w?:?[\\\\|/].*"))
862:                        value = getBaseFolder() + File.separator + value;
863:
864:                    try {
865:                        value = new File(value).getCanonicalPath();
866:                    } catch (IOException e) {
867:                        return value;
868:                    }
869:                }
870:
871:                return value;
872:            }
873:
874:            protected Map<Class<? extends Component>, Style> getDefaultStyles() {
875:                return compTypeToStyle;
876:            }
877:
878:            protected Map<String, Color> getSystemColors() {
879:                return systemColors;
880:            }
881:
882:            protected Map<String, String> getSystemImages() {
883:                return systemImages;
884:            }
885:
886:            void setPriorFocus(Component comp) {
887:                priorFocus = new WeakReference<Component>(comp);
888:            }
889:
890:            /**
891:             * @return the base folder of the system
892:             */
893:            public abstract String getBaseFolder();
894:
895:            /**
896:             * 
897:             * @param pathname
898:             * @return
899:             */
900:            public File getRelativeFile(String pathname) {
901:                return new File(appendBaseFolder(pathname));
902:            }
903:
904:            /**
905:             * 
906:             * @param parent
907:             * @param child
908:             * @return
909:             */
910:            public File getRelativeFile(String parent, String child) {
911:                return new File(appendBaseFolder(parent), child);
912:            }
913:
914:            private String appendBaseFolder(String s) {
915:                String ret = null;
916:
917:                if (s != null && !s.matches("^\\w?:?[\\\\|/].*")) {
918:                    if (ret == null)
919:                        ret = getBaseFolder() + File.separator + s;
920:                }
921:
922:                ret = (ret == null ? s : ret);
923:                return ret;
924:            }
925:
926:            protected Object setPackagePrivateMember(String memberName,
927:                    Component comp, Object value) {
928:                if (memberName.equals("renderer")) {
929:                    ((AbstractComponent) comp).setRenderer((Renderer) value);
930:                } else if (memberName.equals("innerWidth")) {
931:                    ((Frame) comp).setInnerWidth((Integer) value);
932:                } else if (memberName.equals("innerHeight")) {
933:                    ((Frame) comp).setInnerHeight((Integer) value);
934:                } else if (memberName.equals("frameSize")) {
935:                    Integer[] size = (Integer[]) value;
936:                    ((Frame) comp).sizeChanged(size[0], size[1]);
937:                } else if (memberName.equals("initDDGBView")) {
938:                    DropDownGridBox.DefaultView v = new DropDownGridBox.DefaultView();
939:                    v.init(null, (GridBox) value);
940:                    return v;
941:                }
942:                return null;
943:            }
944:
945:            protected abstract void captureThread();
946:
947:            protected abstract void releaseThread();
948:
949:            protected abstract void showWindow(Window w);
950:
951:            protected abstract void hideWindow(Window w);
952:
953:            protected abstract FileChooser.FileInfo getFileInfo();
954:
955:            protected abstract String getQualifiedURL(String location);
956:
957:            protected abstract void removeFileFromMap(String location);
958:
959:            /**
960:             * 
961:             * @param task
962:             * @param milliseconds
963:             */
964:            public abstract void addTimerTask(Runnable task, long milliseconds);
965:
966:            /**
967:             * 
968:             * @param task
969:             * @param milliseconds
970:             * @param repeat
971:             */
972:            public abstract void addTimerTask(Runnable task, long milliseconds,
973:                    boolean repeat);
974:
975:            /**
976:             * 
977:             * @param task
978:             */
979:            public abstract void resetTimerTask(Runnable task);
980:
981:            /**
982:             * 
983:             * @param task
984:             */
985:            public abstract void removeTimerTask(Runnable task);
986:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.