KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > resource > ImageRegistry


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Steven Ketcham (sketcham@dsicdi.com) - Bug 42451
11  * [Dialogs] ImageRegistry throws null pointer exception in
12  * application with multiple Display's
13  *******************************************************************************/

14 package org.eclipse.jface.resource;
15
16 import java.util.HashMap JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.Map JavaDoc;
19
20 import org.eclipse.jface.dialogs.Dialog;
21 import org.eclipse.core.runtime.Assert;
22 import org.eclipse.swt.SWT;
23 import org.eclipse.swt.graphics.Device;
24 import org.eclipse.swt.graphics.Image;
25 import org.eclipse.swt.graphics.ImageData;
26 import org.eclipse.swt.widgets.Display;
27
28 /**
29  * An image registry maintains a mapping between symbolic image names
30  * and SWT image objects or special image descriptor objects which
31  * defer the creation of SWT image objects until they are needed.
32  * <p>
33  * An image registry owns all of the image objects registered
34  * with it, and automatically disposes of them when the SWT Display
35  * that creates the images is disposed. Because of this, clients do not
36  * need to (indeed, must not attempt to) dispose of these images themselves.
37  * </p>
38  * <p>
39  * Clients may instantiate this class (it was not designed to be subclassed).
40  * </p>
41  * <p>
42  * Unlike the FontRegistry, it is an error to replace images. As a result
43  * there are no events that fire when values are changed in the registry
44  * </p>
45  */

46 public class ImageRegistry {
47     /**
48      * display used when getting images
49      */

50     private Display display;
51
52     private ResourceManager manager;
53
54     private Map JavaDoc table;
55     
56     private Runnable JavaDoc disposeRunnable = new Runnable JavaDoc() {
57         public void run() {
58             dispose();
59         }
60     };
61     
62     /**
63      * Contains the data for an entry in the registry.
64      */

65     private static class Entry {
66         /** the image */
67         protected Image image;
68
69         /** the descriptor */
70         protected ImageDescriptor descriptor;
71     }
72     
73     private static class OriginalImageDescriptor extends ImageDescriptor {
74         private Image original;
75         private int refCount = 0;
76         private Device originalDisplay;
77         
78         /**
79          * @param original the original image
80          * @param originalDisplay the device the image is part of
81          */

82         public OriginalImageDescriptor(Image original, Device originalDisplay) {
83             this.original = original;
84             this.originalDisplay = originalDisplay;
85         }
86         
87         public Object JavaDoc createResource(Device device) throws DeviceResourceException {
88             if (device == originalDisplay) {
89                 refCount++;
90                 return original;
91             }
92             return super.createResource(device);
93         }
94         
95         public void destroyResource(Object JavaDoc toDispose) {
96             if (original == toDispose) {
97                 refCount--;
98                 if (refCount == 0) {
99                     original.dispose();
100                     original = null;
101                 }
102             } else {
103                 super.destroyResource(toDispose);
104             }
105         }
106
107         /* (non-Javadoc)
108          * @see org.eclipse.jface.resource.ImageDescriptor#getImageData()
109          */

110         public ImageData getImageData() {
111             return original.getImageData();
112         }
113     }
114         
115     /**
116      * Creates an empty image registry.
117      * <p>
118      * There must be an SWT Display created in the current
119      * thread before calling this method.
120      * </p>
121      */

122     public ImageRegistry() {
123         this(Display.getCurrent());
124     }
125
126     /**
127      * Creates an empty image registry using the given resource manager to allocate images.
128      *
129      * @param manager the resource manager used to allocate images
130      *
131      * @since 3.1
132      */

133     public ImageRegistry(ResourceManager manager) {
134         Assert.isNotNull(manager);
135         Device dev = manager.getDevice();
136         if (dev instanceof Display) {
137             this.display = (Display)dev;
138         }
139         this.manager = manager;
140         manager.disposeExec(disposeRunnable);
141     }
142     
143     /**
144      * Creates an empty image registry.
145      *
146      * @param display this <code>Display</code> must not be
147      * <code>null</code> and must not be disposed in order
148      * to use this registry
149      */

150     public ImageRegistry(Display display) {
151         this(JFaceResources.getResources(display));
152     }
153     
154     /**
155      * Returns the image associated with the given key in this registry,
156      * or <code>null</code> if none.
157      *
158      * @param key the key
159      * @return the image, or <code>null</code> if none
160      */

161     public Image get(String JavaDoc key) {
162
163         // can be null
164
if (key == null) {
165             return null;
166         }
167         
168         if (display != null) {
169             /**
170              * NOTE, for backwards compatibility the following images are supported
171              * here, they should never be disposed, hence we explicitly return them
172              * rather then registering images that SWT will dispose.
173              *
174              * Applications should go direclty to SWT for these icons.
175              *
176              * @see Display.getSystemIcon(int ID)
177              */

178             int swtKey = -1;
179             if (key.equals(Dialog.DLG_IMG_INFO)) {
180                 swtKey = SWT.ICON_INFORMATION;
181             }
182             if (key.equals(Dialog.DLG_IMG_QUESTION)) {
183                 swtKey = SWT.ICON_QUESTION;
184             }
185             if (key.equals(Dialog.DLG_IMG_WARNING)) {
186                 swtKey = SWT.ICON_WARNING;
187             }
188             if (key.equals(Dialog.DLG_IMG_ERROR)) {
189                 swtKey = SWT.ICON_ERROR;
190             }
191             // if we actually just want to return an SWT image do so without
192
// looking in the registry
193
if (swtKey != -1) {
194                 final Image[] image = new Image[1];
195                 final int id = swtKey;
196                 display.syncExec(new Runnable JavaDoc() {
197                     public void run() {
198                         image[0] = display.getSystemImage(id);
199                     }
200                 });
201                 return image[0];
202             }
203         }
204
205         Entry entry = getEntry(key);
206         if (entry == null) {
207             return null;
208         }
209         
210         if (entry.image == null) {
211             entry.image = manager.createImageWithDefault(entry.descriptor);
212         }
213         
214         return entry.image;
215     }
216
217     /**
218      * Returns the descriptor associated with the given key in this registry,
219      * or <code>null</code> if none.
220      *
221      * @param key the key
222      * @return the descriptor, or <code>null</code> if none
223      * @since 2.1
224      */

225     public ImageDescriptor getDescriptor(String JavaDoc key) {
226         Entry entry = getEntry(key);
227         if (entry == null) {
228             return null;
229         }
230         
231         return entry.descriptor;
232     }
233
234     /**
235      * Adds (or replaces) an image descriptor to this registry. The first time
236      * this new entry is retrieved, the image descriptor's image will be computed
237      * (via </code>ImageDescriptor.createImage</code>) and remembered.
238      * This method replaces an existing image descriptor associated with the
239      * given key, but fails if there is a real image associated with it.
240      *
241      * @param key the key
242      * @param descriptor the ImageDescriptor
243      * @exception IllegalArgumentException if the key already exists
244      */

245     public void put(String JavaDoc key, ImageDescriptor descriptor) {
246         Entry entry = getEntry(key);
247         if (entry == null) {
248             entry = new Entry();
249             getTable().put(key, entry);
250         }
251         
252         if (entry.image != null) {
253             throw new IllegalArgumentException JavaDoc(
254                     "ImageRegistry key already in use: " + key); //$NON-NLS-1$
255
}
256         
257         entry.descriptor = descriptor;
258     }
259
260     /**
261      * Adds an image to this registry. This method fails if there
262      * is already an image or descriptor for the given key.
263      * <p>
264      * Note that an image registry owns all of the image objects registered
265      * with it, and automatically disposes of them when the SWT Display is disposed.
266      * Because of this, clients must not register an image object
267      * that is managed by another object.
268      * </p>
269      *
270      * @param key the key
271      * @param image the image, should not be <code>null</code>
272      * @exception IllegalArgumentException if the key already exists
273      */

274     public void put(String JavaDoc key, Image image) {
275         Entry entry = getEntry(key);
276         
277         if (entry == null) {
278             entry = new Entry();
279             putEntry(key, entry);
280         }
281         
282         if (entry.image != null || entry.descriptor != null) {
283             throw new IllegalArgumentException JavaDoc(
284                     "ImageRegistry key already in use: " + key); //$NON-NLS-1$
285
}
286         
287         // Should be checking for a null image here.
288
// Current behavior is that a null image won't be caught until dispose.
289
// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=130315
290
entry.image = image;
291         entry.descriptor = new OriginalImageDescriptor(image, manager.getDevice());
292         
293         try {
294             manager.create(entry.descriptor);
295         } catch (DeviceResourceException e) {
296         }
297     }
298
299     /**
300      * Removes an image from this registry.
301      * If an SWT image was allocated, it is disposed.
302      * This method has no effect if there is no image or descriptor for the given key.
303      * @param key the key
304      */

305     public void remove(String JavaDoc key) {
306         ImageDescriptor descriptor = getDescriptor(key);
307         if (descriptor != null) {
308             manager.destroy(descriptor);
309             getTable().remove(key);
310         }
311     }
312
313     private Entry getEntry(String JavaDoc key) {
314         return (Entry) getTable().get(key);
315     }
316
317     private void putEntry(String JavaDoc key, Entry entry) {
318         getTable().put(key, entry);
319     }
320
321     private Map JavaDoc getTable() {
322         if (table == null) {
323             table = new HashMap JavaDoc(10);
324         }
325         return table;
326     }
327     
328     /**
329      * Disposes this image registry, disposing any images
330      * that were allocated for it, and clearing its entries.
331      *
332      * @since 3.1
333      */

334     public void dispose() {
335         manager.cancelDisposeExec(disposeRunnable);
336         
337         if (table != null) {
338             for (Iterator JavaDoc i = table.values().iterator(); i.hasNext();) {
339                 Entry entry = (Entry) i.next();
340                 if (entry.image != null) {
341                     manager.destroyImage(entry.descriptor);
342                 }
343             }
344             table = null;
345         }
346         display = null;
347     }
348 }
349
Popular Tags