View Javadoc
1   package eu.simuline.util;
2   
3   import javax.swing.ImageIcon;
4   
5   import java.net.URL;
6   import java.net.MalformedURLException;
7   
8   import java.util.Map;
9   import java.util.HashMap;
10  import org.javalobby.icons20x20.Open;
11  import org.javalobby.icons20x20.Hammer;
12  
13  /**
14   * Provides a single method only, {@link #getIcon(Class)}, 
15   * which returns the icon associated with the given class. 
16   * The class must be a subclass of {@link GifResource} as is {@link Open}. 
17   * That class is also an example for using {@link GifResource}s: 
18   * Just derive a class from {@link GifResource} 
19   * and put it into a package 
20   * (<code>org.javalobby.icons16x16</code> in this case) 
21   * pointing to the according gif-image 
22   * which can be found in this case 
23   * in <code>src/main/resources/org/javalobby/icons16x16/Open.gif</code>. 
24   *
25   * Created: Sun Jun  4 20:50:12 2006
26   *
27   * @author <a href="mailto:ernst.reissner@simuline.eu">Ernst Reissner</a>
28   * @version 1.0
29   */
30  public abstract class GifResource {
31  
32      /* -------------------------------------------------------------------- *
33       * private class constants.                                             *
34       * -------------------------------------------------------------------- */
35  
36      /**
37       * The separator in urls. 
38       * Note that this is unified unlike file separators 
39       * which depend on the operating system. 
40       */
41      private static final String URL_SEP = "/";
42  
43      /**
44       * The ending of a java class file. 
45       */
46      private static final String CLASS_END = "class";
47  
48      /**
49       * The ending of a gif file. 
50       */
51      private static final String GIF_END = "gif";
52  
53      /**
54       * <code>target/classes/</code>: the directory of the classfiles 
55       * within the simuline-developing environment. 
56       * **** bad: path is hardcoded **** 
57       */
58      private static final String CLASS    = URL_SEP + "target" 
59  	+ URL_SEP  + "classes" + URL_SEP;
60  
61      /**
62       * <code>src/main/resource/</code>: the directory of the resources
63       * within simuline-developing environment. 
64       * **** bad: path is hardcoded **** 
65       */
66      private static final String RESOURCE = 
67  	URL_SEP + "src/main/resources" + URL_SEP; // **** URL_SEP and /
68  
69      /**
70       * A cache for gif-files represented by GifResources. 
71       */
72      private static final Map<Class<?>, ImageIcon> GIFS = 
73  	new HashMap<Class<?>, ImageIcon>();
74  
75      /* -------------------------------------------------------------------- *
76       * fields.                                                              *
77       * -------------------------------------------------------------------- */
78  
79      //private Icon icon;
80  
81      /* -------------------------------------------------------------------- *
82       * constructor.                                                         *
83       * -------------------------------------------------------------------- */
84  
85      /*
86       * Creates a new <code>GifResource</code> instance.
87       * To this end **** is this constructor really needed???? **** 
88       * <ul>
89       * <li>
90       * converts the classname into the name of the corresponding file, 
91       * <li>
92       * replaces class files directory by resource files directory, 
93       * <li>
94       * adds the GIF-ending, 
95       * <li>
96       * forms the corresponding url and finally 
97       * <li>
98       * read the so determined gif file into the icon {@link #icon}. 
99       * </ul>
100      */
101 /*
102     protected GifResource() {
103 	String path = this.getClass().getName()
104 	    .replace('.','/')+"."+CLASS_END;
105 	
106 	//***NO PURE JAVA
107 	URL url = ClassLoader.getSystemResource(path);
108 	//System.out.println("url: "+url);
109 	path = url.toString().replace(CLASS_END,GIF_END);
110 	//System.out.println("path2: "+path);
111 	path = path.replace(CLASS,RESOURCE); /// **** a little weak
112 	//System.out.println("path3: "+path);
113 	try {
114 	    url = new URL(path);
115 	} catch (MalformedURLException e) {
116 	    throw new UnsatisfiedLinkError// NOPMD
117 		("Resource not found: "+path);
118 	}
119 	this.icon = new ImageIcon(url);
120     }
121 */
122     /* -------------------------------------------------------------------- *
123      * methods.                                                             *
124      * -------------------------------------------------------------------- */
125 /*
126     // **** really needed? 
127     public Icon getIcon() {
128 	return this.icon;
129     }
130 
131 */
132     /**
133      * Converts a GifResource class into the corresponding icon. 
134      * This is done in the following steps: 
135      * If the image is cached in {@link #GIFS}, take this one. 
136      * Else load it into {@link #GIFS}as described below 
137      * before taking it from {@link #GIFS}. 
138      * <p>
139      * Loading an image consists in 
140      * loading the class-file associated with the image, 
141      * determining the according gif-file 
142      * and creating the according ImageIcon. 
143      * 
144      * @param res
145      *    a subclass of GifResource. 
146      * @return
147      *    the icon determined by the given class. 
148      *    <p>
149      *    CAUTION: Note that an icon is returned 
150      *    even if there is no according gif-image. 
151      *    This image can be identified by width <code>-1</code> 
152      *    which is an undocumented property. 
153      */
154     public static ImageIcon getIcon(Class<? extends GifResource> res) {
155 	ImageIcon ret = GIFS.get(res);
156 	if (ret == null) {
157 	    // Here the icon is not yet loaded. 
158 
159 	    // transform class into path of class file name... 
160 	    String path = res.getName().replace('.', '/') + "." + CLASS_END;
161 	    //***NO PURE JAVA
162 	    // ... and further into an URL (ensuring that this class exists) 
163 	    URL url = ClassLoader.getSystemResource(path);
164 	    assert url != null; // because class exists 
165 
166 	    // The class URL into the gif-image url 
167 	    path = url.toString().replaceAll(CLASS_END + "\\z", GIF_END);
168 	    //System.out.println("path2: "+path);
169 	    path = path.replace(CLASS, RESOURCE); /// **** a little weak
170 	    //System.out.println("path3: "+path);
171 	    try {
172 		url = new URL(path);
173 	    } catch (MalformedURLException e) {
174 		throw new UnsatisfiedLinkError// NOPMD
175 		    ("Resource not found: " + path);
176 	    }
177 
178 	    // **** the following works even 
179 	    // if the url does not point to any file.
180 	    GIFS.put(res, new ImageIcon(url));
181 	    ret = GIFS.get(res);
182 	}
183 	assert ret == GIFS.get(res);
184 
185 	return ret;
186     }
187 
188     public static final void main(String[] args) {
189 	ImageIcon icon = getIcon(Hammer.class);
190 	System.out.println("icon: " + icon.getImage());
191 	System.out.println("icon: " + icon.getIconWidth());
192     }
193 }