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 }