source: josm/trunk/src/org/openstreetmap/josm/tools/ImageProvider.java@ 1180

Last change on this file since 1180 was 1169, checked in by stoecker, 15 years ago

removed usage of tab stops

  • Property svn:eol-style set to native
File size: 7.1 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.tools;
3
4import java.awt.Cursor;
5import java.awt.Graphics;
6import java.awt.GraphicsConfiguration;
7import java.awt.GraphicsEnvironment;
8import java.awt.Image;
9import java.awt.Point;
10import java.awt.Toolkit;
11import java.awt.Transparency;
12import java.awt.image.BufferedImage;
13import java.io.File;
14import java.net.MalformedURLException;
15import java.net.URL;
16import java.util.Arrays;
17import java.util.Collection;
18import java.util.HashMap;
19import java.util.LinkedList;
20import java.util.List;
21import java.util.Map;
22
23import javax.swing.Icon;
24import javax.swing.ImageIcon;
25
26import org.openstreetmap.josm.Main;
27
28/**
29 * Helperclass to support the application with images.
30 * @author imi
31 */
32public class ImageProvider {
33
34 /**
35 * Position of an overlay icon
36 * @author imi
37 */
38 public static enum OverlayPosition {NORTHWEST, NORTHEAST, SOUTHWEST, SOUTHEAST}
39
40 /**
41 * The icon cache
42 */
43 private static Map<String, Image> cache = new HashMap<String, Image>();
44
45 /**
46 * Add here all ClassLoader whose ressource should be searched.
47 * Plugin's class loaders are added by main.
48 */
49 public static final List<ClassLoader> sources = new LinkedList<ClassLoader>();
50
51 /**
52 * Return an image from the specified location.
53 *
54 * @param subdir The position of the directory, e.g. "layer"
55 * @param name The icons name (without the ending of ".png")
56 * @return The requested Image.
57 */
58 public static ImageIcon get(String subdir, String name) {
59 ImageIcon icon = getIfAvailable(subdir, name);
60 if (icon == null) {
61 String ext = name.indexOf('.') != -1 ? "" : ".png";
62 throw new NullPointerException("/images/"+subdir+name+ext+" not found");
63 }
64 return icon;
65 }
66
67 public static ImageIcon getIfAvailable(String subdir, String name)
68 {
69 return getIfAvailable((Collection<String>)null, null, subdir, name);
70 }
71 public static final ImageIcon getIfAvailable(String[] dirs, String id, String subdir, String name)
72 {
73 return getIfAvailable(Arrays.asList(dirs), id, subdir, name);
74 }
75
76 /**
77 * Like {@link #get(String)}, but does not throw and return <code>null</code>
78 * in case of nothing is found. Use this, if the image to retrieve is optional.
79 */
80 public static ImageIcon getIfAvailable(Collection<String> dirs, String id, String subdir, String name)
81 {
82 if (name == null)
83 return null;
84 if (subdir == null)
85 subdir = "";
86 else if (!subdir.equals(""))
87 subdir += "/";
88 String ext = name.indexOf('.') != -1 ? "" : ".png";
89 String full_name = subdir+name+ext;
90 String cache_name = full_name;
91 /* cache separately */
92 if(dirs != null && dirs.size() > 0)
93 cache_name = "id:"+id+":"+full_name;
94
95 Image img = cache.get(cache_name);
96 if (img == null) {
97 // getImageUrl() does a ton of "stat()" calls and gets expensive
98 // and redundant when you have a whole ton of objects. So,
99 // index the cache by the name of the icon we're looking for
100 // and don't bother to create a URL unless we're actually
101 // creating the image.
102 URL path = getImageUrl(full_name, dirs);
103 if (path == null)
104 return null;
105 img = Toolkit.getDefaultToolkit().createImage(path);
106 cache.put(cache_name, img);
107 }
108
109 return new ImageIcon(img);
110 }
111
112 private static URL getImageUrl(String path, String name)
113 {
114 if(path.startsWith("resource://"))
115 {
116 String p = path.substring("resource://".length());
117 for (ClassLoader source : sources)
118 {
119 URL res;
120 if ((res = source.getResource(p+name)) != null)
121 return res;
122 }
123 }
124 else
125 {
126 try {
127 File f = new File(path, name);
128 if(f.exists())
129 return f.toURI().toURL();
130 } catch (MalformedURLException e) {}
131 }
132 return null;
133 }
134
135 private static URL getImageUrl(String imageName, Collection<String> dirs)
136 {
137 URL u;
138 // Try passed directories first
139 if(dirs != null)
140 {
141 for (String name : dirs)
142 {
143 u = getImageUrl(name, imageName);
144 if(u != null) return u;
145 }
146 }
147 // Try user-preference directory
148 u = getImageUrl(Main.pref.getPreferencesDir()+"images", imageName);
149 if(u != null) return u;
150
151 // Try plugins and josm classloader
152 u = getImageUrl("resource://images/", imageName);
153 if(u != null) return u;
154
155 // Try all other ressource directories
156 for (String location : Main.pref.getAllPossiblePreferenceDirs())
157 {
158 u = getImageUrl(location+"images", imageName);
159 if(u != null) return u;
160 u = getImageUrl(location, imageName);
161 if(u != null) return u;
162 }
163 return null;
164 }
165
166 /**
167 * Shortcut for get("", name);
168 */
169 public static ImageIcon get(String name) {
170 return get("", name);
171 }
172
173 public static Cursor getCursor(String name, String overlay) {
174 ImageIcon img = get("cursor",name);
175 if (overlay != null)
176 img = overlay(img, "cursor/modifier/"+overlay, OverlayPosition.SOUTHEAST);
177 Cursor c = Toolkit.getDefaultToolkit().createCustomCursor(img.getImage(),
178 name.equals("crosshair") ? new Point(10,10) : new Point(3,2), "Cursor");
179 return c;
180 }
181
182 /**
183 * @return an icon that represent the overlay of the two given icons. The
184 * second icon is layed on the first relative to the given position.
185 */
186 public static ImageIcon overlay(Icon ground, String overlayImage, OverlayPosition pos) {
187 GraphicsConfiguration conf = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
188 int w = ground.getIconWidth();
189 int h = ground.getIconHeight();
190 ImageIcon overlay = ImageProvider.get(overlayImage);
191 int wo = overlay.getIconWidth();
192 int ho = overlay.getIconHeight();
193 BufferedImage img = conf.createCompatibleImage(w,h, Transparency.TRANSLUCENT);
194 Graphics g = img.createGraphics();
195 ground.paintIcon(null, g, 0, 0);
196 int x = 0, y = 0;
197 switch (pos) {
198 case NORTHWEST:
199 x = 0;
200 y = 0;
201 break;
202 case NORTHEAST:
203 x = w-wo;
204 y = 0;
205 break;
206 case SOUTHWEST:
207 x = 0;
208 y = h-ho;
209 break;
210 case SOUTHEAST:
211 x = w-wo;
212 y = h-ho;
213 break;
214 }
215 overlay.paintIcon(null, g, x, y);
216 return new ImageIcon(img);
217 }
218
219 static {
220 try {
221 sources.add(ClassLoader.getSystemClassLoader());
222 } catch (SecurityException ex) {
223 sources.add(ImageProvider.class.getClassLoader());
224 }
225 }
226}
Note: See TracBrowser for help on using the repository browser.