KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdesktop > swing > Application


1 /*
2  * $Id: Application.java,v 1.2 2004/08/30 22:05:30 davidson1 Exp $
3  *
4  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
5  * Santa Clara, California 95054, U.S.A. All rights reserved.
6  */

7
8 package org.jdesktop.swing;
9
10 import java.applet.Applet JavaDoc;
11 import java.applet.AppletContext JavaDoc;
12
13 import java.awt.Component JavaDoc;
14 import java.awt.Container JavaDoc;
15 import java.awt.Image JavaDoc;
16 import java.awt.Window JavaDoc;
17
18 import java.beans.Beans JavaDoc;
19
20 import java.io.File JavaDoc;
21
22 import java.lang.reflect.Method JavaDoc;
23
24 import java.net.URL JavaDoc;
25 import java.net.MalformedURLException JavaDoc;
26
27 import java.util.ArrayList JavaDoc;
28 import java.util.HashMap JavaDoc;
29 import java.util.Hashtable JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Vector JavaDoc;
34
35 import javax.swing.ActionMap JavaDoc;
36 import javax.swing.JApplet JavaDoc;
37 import javax.swing.JRootPane JavaDoc;
38 import javax.swing.Icon JavaDoc;
39 import javax.swing.ImageIcon JavaDoc;
40 import javax.swing.SwingUtilities JavaDoc;
41
42 import org.jdesktop.swing.event.SelectionListener;
43
44 import org.jdesktop.swing.actions.ActionManager;
45
46 import org.jdesktop.swing.utils.SwingWorker;
47 /**
48  * <p>
49  * Class which represents central state and properties for a single client
50  * application which can be either a standalone Java application (typically
51  * initiated using Java WebStart) or a set of one or more Java applets which
52  * share the same code base. There should only be a single Application instance
53  * per client application.</p>
54  * <p>
55  * This class also encapsulates any functionality which has variable API
56  * between applets and Java WebStart applications so that UI components can
57  * reliably talk to a single interface for such services.</p>
58  *
59  * @author Amy Fowler
60  * @version 1.0
61  */

62 public class Application {
63
64     // Index values for toplevels array
65
private static final int WINDOWS = 0;
66     private static final int APPLETS = 1;
67
68     private static Map JavaDoc appMap = new Hashtable JavaDoc();
69     private static Map JavaDoc imageCache = new HashMap JavaDoc();
70
71     private ActionMap JavaDoc actionMap;
72
73     // The ActionManager instance
74
// TODO: investigate if this introduces a circular dependency.
75
private ActionManager manager;
76
77     private String JavaDoc title = "JDNC Application";
78     private String JavaDoc versionString = "";
79
80     private Image JavaDoc splashImage = null;
81     private Image JavaDoc titleBarImage = null;
82
83     private URL JavaDoc baseURL;
84     private Vector JavaDoc toplevel[] = new Vector JavaDoc[2];
85
86     private List JavaDoc selectionListeners;
87
88     /**
89      * Private constructor so that an Application can't be directly instantated.
90     private Application() {
91     }
92
93     /**
94      * Factory method for obtaining the Application instance associated with this
95      * application. The Application object will be instantiated if it does not
96      * already exist. This method is intended for use by standalone applications
97      * where there may be one and only one JDNCapp instance.
98      * @return Application instance for application
99      */

100     public static Application getInstance() {
101         return getInstance("theone");
102     }
103
104     /**
105      * Factory method for obtaining the Application instance associated with the
106      * application designated by the specified key. The Application object will
107      * be instantiated if it does not already exist. This method is intended
108      * for use by applets, where there may be multiple Application instances in
109      * a running VM.
110      * @param key object designating the application
111      * @return Application instance for application
112      */

113     public static Application getInstance(Object JavaDoc key) {
114         Application app = null;
115         synchronized(appMap) {
116             app = (Application) appMap.get(key);
117             if (app == null) {
118         try {
119             ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
120             app = (Application)Beans.instantiate(cl,
121                              "org.jdesktop.swing.Application");
122             appMap.put(key, app);
123         } catch (Exception JavaDoc ex) {
124             // XXX eception
125
ex.printStackTrace();
126         }
127         //REMIND(aim): memory leak - when to remove the app entry for applets
128
}
129         }
130         return app;
131     }
132
133     /**
134      * Convenience method for getting the JDNCapp instance given
135      * a component instance. The component instance must be contained in
136      * a containent hierarchy which has either a Window or an Applet instance
137      * as the root.
138      *
139      * @param c the ui component
140      * @return Application instance for the specified component's application
141      */

142     public static Application getApp(Component JavaDoc c) {
143         Application app = null;
144         Container JavaDoc parent = c instanceof Container JavaDoc? (Container JavaDoc)c : c.getParent();
145         while (parent != null) {
146             if (parent instanceof Window JavaDoc) {
147                 app = findApp(WINDOWS, parent);
148                 break;
149             }
150             else if (parent instanceof Applet JavaDoc) {
151                 app = findApp(APPLETS, parent);
152                 break;
153             }
154             else {
155                 parent = parent.getParent();
156             }
157         }
158     // There is no app associated with this component.
159
// Create one and register it with the root container
160
if (app == null) {
161         Component JavaDoc p = SwingUtilities.getRoot(c);
162         if (p != null) {
163         app = Application.getInstance(p);
164         if (p instanceof Applet JavaDoc) {
165             app.registerApplet((Applet JavaDoc)p);
166         } else {
167             app.registerWindow((Window JavaDoc)p);
168         }
169         }
170     }
171         return app;
172     }
173
174     private static Application findApp(int type, Component JavaDoc c) {
175         Application app = null;
176         Iterator JavaDoc apps = appMap.values().iterator();
177         while (app == null && apps.hasNext()) {
178             Application a = (Application) apps.next();
179             if (a.toplevel[type] != null) {
180                 if (a.toplevel[type].contains(c)) {
181                     app = a;
182                     break;
183                 }
184             }
185         }
186         return app;
187     }
188
189     /**
190      * Return the action manager for this application.
191      *
192      * @return the action manager instance
193      */

194     public ActionManager getActionManager() {
195     if (manager == null) {
196         manager = new ActionManager();
197     }
198     return manager;
199     }
200
201     /**
202      * Sets the &quot;baseURL&quot; property of this application.
203      * @param baseURL URL of codebase for this application
204      */

205     public void setBaseURL(URL JavaDoc baseURL) {
206         this.baseURL = baseURL;
207     }
208
209     /**
210      * @return URL of codebase for this application
211      */

212     public URL JavaDoc getBaseURL() {
213         return baseURL;
214     }
215
216     /**
217      * Will retrieve the applet base url if this application is running in an
218      * applet. Otherwise, it will try to retrieve the base URL of the
219      * xml configuration file.
220      */

221     public static URL JavaDoc getBaseURL(Object JavaDoc obj) {
222     URL JavaDoc url = null;
223     if (obj instanceof Component JavaDoc) {
224         Container JavaDoc parent = SwingUtilities.getAncestorOfClass(JApplet JavaDoc.class,
225                                  (Component JavaDoc)obj);
226         if (parent != null) {
227         JApplet JavaDoc applet = (JApplet JavaDoc)parent;
228         url = applet.getDocumentBase();
229         } else {
230         WebStartContext context = WebStartContext.getInstance();
231         // FIXME: this should be spawned in a SwingWorker.
232
url = context.getDocumentBase();
233         }
234         if (url == null) {
235         Application app = Application.getApp((Component JavaDoc)obj);
236         if (app != null) {
237             url = app.getBaseURL();
238         }
239         }
240     }
241     if (url == null) {
242         url = Application.getInstance().getBaseURL();
243     }
244     return url;
245     }
246
247     /**
248      * Fetches a url of a resource value using the clasloader and
249      * relative path of obj.
250      * Will first try to load from the classpath, then the direct url and then
251      * look for a base url.
252      */

253     public static URL JavaDoc getURL(String JavaDoc value, Object JavaDoc obj) {
254     URL JavaDoc url = getURLResource(value, obj);
255     if (url == null) {
256         try {
257         url = new URL JavaDoc(value);
258         } catch (MalformedURLException JavaDoc ex) {
259         // fall through
260
}
261     }
262     if (url == null) {
263         URL JavaDoc base = Application.getBaseURL(obj);
264         if (base != null) {
265         try {
266             url = new URL JavaDoc(base, value);
267         } catch (MalformedURLException JavaDoc e) {
268             // fall through
269
}
270         }
271     }
272     if (url == null) {
273         // System.err.println("getURL: no url for value: " + value + " obj: " + obj);
274
}
275     return url;
276     }
277
278     public static URL JavaDoc getURLResource(String JavaDoc value, Object JavaDoc obj) {
279     return obj.getClass().getResource(value);
280     }
281
282
283     public static Image JavaDoc getImage(String JavaDoc name, Object JavaDoc obj) {
284     Icon JavaDoc icon = getIcon(name, obj);
285     if (icon != null) {
286         return ((ImageIcon JavaDoc)icon).getImage();
287     } else {
288         return null;
289     }
290     }
291
292     public static Icon JavaDoc getIcon(String JavaDoc name, Object JavaDoc obj) {
293     Icon JavaDoc icon = null;
294
295     if (name == null || (icon = (Icon JavaDoc)imageCache.get(name)) != null) {
296         return icon;
297     }
298
299     URL JavaDoc fileLoc = getURL(name, obj);
300     if (fileLoc != null && (icon = new ImageIcon JavaDoc(fileLoc)) != null) {
301         imageCache.put(name, icon);
302     }
303     return icon;
304     }
305
306     /**
307      * Display the document referenced by the url in a browser.
308      * <p>
309      * If the application
310      * is an Applet then the document will be shown from the browser from which it
311      * has been launched. If the application has been launched from Java WebStart
312      * then it will use the javax.jnlp.BasicService to show the document. If this
313      * is a standalone application then it will use the platform browser to show
314      * the document.
315      *
316      * @param url an absolute URL giving locationto display
317      * @param target indicates where to display the page
318      * @see java.applet.AppletContext#showDocument(java.net.URL, java.lang.String)
319      * @see javax.jnlp.BasicService#showDocument
320      */

321     public void showDocument(final URL JavaDoc url, final String JavaDoc target) {
322     if (isRunningApplet()) {
323         // show the document in the first applet.
324
Iterator JavaDoc iter = getApplets();
325         if (iter != null) {
326         // Get the first applet
327
Applet JavaDoc applet = (Applet JavaDoc)iter.next();
328         final AppletContext JavaDoc context = applet.getAppletContext();
329         // if target is _self, _parent, _top, _blank, show the document in
330
// a browser.
331
SwingWorker worker = new SwingWorker() {
332             public Object JavaDoc construct() {
333                 context.showDocument(url, target);
334                 return null;
335             }
336             };
337         worker.start();
338         }
339     } else if (isRunningWebStart()) {
340         final WebStartContext context = WebStartContext.getInstance();
341         SwingWorker worker = new SwingWorker() {
342             public Object JavaDoc construct() {
343             context.showDocument(url, target);
344             return null;
345             }
346         };
347         worker.start();
348     } else {
349         // The application is running stand alone so use the platform browser
350
String JavaDoc[] command = null;
351         String JavaDoc os = System.getProperty("os.name").toLowerCase();
352         if (os.indexOf("os x") >= 0) {
353         // Mac OSX
354
command = new String JavaDoc[] { "open", url.toExternalForm() };
355         }
356         else if (os.indexOf("wind") >= 0) {
357         // Windows variants
358
command = new String JavaDoc[] { "rundll32 url.dll,FileProtocolHandler",
359                      url.toExternalForm() };
360         }
361         else {
362         // mozilla by default
363
command = new String JavaDoc[] { "mozilla", "-remote",
364                      "openurl(" + url.toExternalForm() + ")"};
365         }
366         executeCommand(command);
367     }
368     }
369
370     /**
371      * Executes the command in a new thread.
372      */

373     void executeCommand(final String JavaDoc[] command) {
374     SwingWorker worker = new SwingWorker() {
375         public Object JavaDoc construct() {
376             try {
377             Runtime.getRuntime().exec(command);
378             } catch (Exception JavaDoc ex) {
379             }
380             return null;
381         }
382         };
383     worker.start();
384     }
385
386     /**
387      * Sets the &quot;splashImage&quot; property of this application.
388      * If set, this image will be rendered in the splash screen which
389      * is displayed momentarily at application startup while the
390      * application initializes.
391      * @param splashImage image displayed in the application's splash screen
392      */

393     public void setSplashImage(Image JavaDoc splashImage) {
394         this.splashImage = splashImage;
395     }
396
397     /**
398      * @return Image displayed in the application's splash screen
399      */

400     public Image JavaDoc getSplashImage() {
401         return splashImage;
402     }
403
404     /**
405      * Sets the &quot;title&quot; property of this application.
406      * @param title string containing the title of this application
407      */

408     public void setTitle(String JavaDoc title) {
409         this.title = title;
410     }
411
412     /**
413      * @return String containing the title of this application
414      */

415     public String JavaDoc getTitle() {
416         return title;
417     }
418
419     /**
420      * Sets the &quot;titleBarImage&quot; property of this application.
421      * If set, this image will be displayed in the titlebar of all UI
422      * windows shown by this application. The placement of this image
423      * within the titlebar is Look and Feel dependent.
424      * @param titleBarImage image displayed in titlebar of application's toplevel windows
425      */

426     public void setTitleBarImage(Image JavaDoc titleBarImage) {
427         this.titleBarImage = titleBarImage;
428     }
429
430     /**
431      * @return image displayed in titlebar of application's toplevel windows
432      */

433     public Image JavaDoc getTitleBarImage() {
434         return titleBarImage;
435     }
436
437     /**
438      * Sets the &quot;versionString&quot; property of this application.
439      * @param versionString string containing the version of this application
440      */

441     public void setVersionString(String JavaDoc versionString) {
442         this.versionString = versionString;
443     }
444
445     /**
446      * @return String containing the version of this application
447      */

448     public String JavaDoc getVersionString() {
449         return versionString;
450     }
451
452     /**
453      * Returns <code>true</code> if running as a standalone application and
454      * returns <code>false</code> if running one or more applets.
455      * @return true if this client is running as an application;
456      * false if running as an applet
457      */

458     public boolean isStandAlone() {
459         return getApplets() == null;
460     }
461
462     /**
463      * Returns a boolean value indicating whether or not this application is
464      * running in the security sandbox
465      *
466      * @return true if the application is in a sandbox; otherwise false
467      */

468     public boolean isRunningInSandbox() {
469         boolean inSandbox = false;
470         try {
471             new File JavaDoc(".");
472         } catch (SecurityException JavaDoc e) {
473             inSandbox = true;
474         }
475         return inSandbox;
476     }
477
478     /**
479      * Returns a boolean value indicating if the application is in an applet.
480      *
481      * @return true if the app is in an applet; otherwise falsee
482      */

483     public boolean isRunningApplet() {
484     return getApplets() != null;
485     }
486
487     /**
488      * Returns a boolean value indicating if the application has been launched with
489      * Java WebStart.
490      *
491      * @return true if running in web start; otherwise false
492      */

493     public boolean isRunningWebStart() {
494     try {
495         // Use reflection so that we dont get classloader errors.
496
Class JavaDoc service = Class.forName("javax.jnlp.ServiceManager");
497         Method JavaDoc lookup = service.getMethod("lookup", new Class JavaDoc[] { String JavaDoc.class });
498         
499         Object JavaDoc basic = lookup.invoke(null,
500              new Object JavaDoc[] { "javax.jnlp.BasicService" });
501         
502         // if we made it here then web start is running.
503
return true;
504     } catch (Exception JavaDoc ex) {
505         // any exception means no
506
}
507     return false;
508     }
509
510     /**
511      * Registers a window with the application instance.
512      */

513     public void registerWindow(Window JavaDoc window) {
514         register(WINDOWS, window);
515     }
516
517     public void unregisterWindow(Window JavaDoc window) {
518         unregister(WINDOWS, window);
519     }
520
521     public void registerApplet(Applet JavaDoc applet) {
522         register(APPLETS, applet);
523     }
524
525     public void unregisterApplet(Applet JavaDoc applet) {
526         unregister(APPLETS, applet);
527     }
528
529     /**
530      * Return the action map associated with this application.
531      * The action map holds all the global application actions.
532      */

533     public ActionMap JavaDoc getActionMap() {
534     if (actionMap == null) {
535         actionMap = new ActionMap JavaDoc();
536     }
537     return actionMap;
538     }
539
540     /**
541      * @return iterator containing all applets registered with this app instance
542      * or null if the app was instantiated from a standalone application
543      */

544     public Iterator JavaDoc getApplets() {
545         return getToplevels(APPLETS);
546     }
547
548     /**
549      * @return iterator containing all windows registered with this app instance
550      * or null if there were no toplevel windows registered
551      */

552     public Iterator JavaDoc getWindows() {
553         return getToplevels(WINDOWS);
554     }
555
556     public void addSelectionListener(SelectionListener l) {
557         if (selectionListeners == null) {
558             selectionListeners = new ArrayList JavaDoc();
559         }
560         selectionListeners.add(l);
561     }
562
563     public void removeSelectionListener(SelectionListener l) {
564         if (selectionListeners != null) {
565             selectionListeners.remove(l);
566         }
567     }
568
569     public SelectionListener[] getSelectionListeners() {
570         if (selectionListeners != null) {
571             return (SelectionListener[])selectionListeners.toArray(
572                              new SelectionListener[1]);
573         }
574         return new SelectionListener[0];
575     }
576
577     private void register(int type, Component JavaDoc c) {
578         if (toplevel[type] == null) {
579             toplevel[type] = new Vector JavaDoc();
580         }
581         toplevel[type].add(c);
582     }
583
584     private void unregister(int type, Component JavaDoc c) {
585         if (toplevel[type] != null) {
586             toplevel[type].remove(c);
587         }
588     }
589
590     private Iterator JavaDoc getToplevels(int type) {
591         if (toplevel[type] == null) {
592             return null;
593         }
594         return toplevel[type].iterator();
595     }
596 }
597
Popular Tags