]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/gfx/ImageCache.java
Sync git svn branch with SVN repository r33269.
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / gfx / ImageCache.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.utils.ui.gfx;\r
13 \r
14 import java.util.concurrent.ConcurrentHashMap;\r
15 import java.util.concurrent.ConcurrentMap;\r
16 \r
17 import org.eclipse.jface.resource.ImageDescriptor;\r
18 import org.eclipse.jface.resource.LocalResourceManager;\r
19 import org.eclipse.jface.resource.ResourceManager;\r
20 import org.eclipse.swt.graphics.Image;\r
21 \r
22 /**\r
23  * ImageCache caches SWT images and does clean dispose.<br>\r
24  * Based on "eclipse - building commercial-quality plug-ins" book's chapter\r
25  * 7.7's example.<br>\r
26  * \r
27  * @author Marko Luukkainen\r
28  * \r
29  * @deprecated Please avoid using this class if at all possible. From a resource\r
30  *             management point-of-view this class does not fit well into a\r
31  *             dynamic OSGi component world. Instead, use JFace\r
32  *             {@link ResourceManager} and particularly\r
33  *             {@link LocalResourceManager}. You can create one in your local\r
34  *             context (a view, editor, bundle activator, etc.) with\r
35  *             <code>new LocalResourceManager(JFaceResources.getResources())</code>\r
36  *             . Remember to dispose your LocalResourceManager when its owner is\r
37  *             disposed. Images can be loaded using\r
38  *             {@link LocalResourceManager#createImage(ImageDescriptor)}.\r
39  * \r
40  */\r
41 public class ImageCache {\r
42 \r
43     /** A singleton cache instance */\r
44     private static final ImageCache                      imageCache = new ImageCache();\r
45 \r
46     /** Descriptor to image mapping */\r
47     private final ConcurrentMap<ImageDescriptor, Image>  images     = new ConcurrentHashMap<ImageDescriptor, Image>();\r
48 \r
49     private final ConcurrentMap<ImageDescriptor, Object> locks      = new ConcurrentHashMap<ImageDescriptor, Object>();\r
50 \r
51     /**\r
52      * Retrieves and caches the specified image.\r
53      * \r
54      * @param imageDescriptor the ImageDescriptor of the Image\r
55      * @return Image valid image or <code>null</code>if the image could not be\r
56      *         created\r
57      */\r
58     public Image getImage(ImageDescriptor imageDescriptor) {\r
59         if (imageDescriptor == null)\r
60             return null;\r
61 \r
62         Image image = images.get(imageDescriptor);\r
63         if (image != null)\r
64             return image;\r
65 \r
66         Object newLock = new Object();\r
67         Object loadLock = locks.putIfAbsent(imageDescriptor, newLock);\r
68         if (loadLock == null)\r
69             loadLock = newLock;\r
70 \r
71         // Localized locking, don't lock the whole class while actually loading the image.\r
72         synchronized (loadLock) {\r
73             image = images.get(imageDescriptor);\r
74             if (image == null) {\r
75                 boolean returnError = false;\r
76                 image = imageDescriptor.createImage(returnError);\r
77                 if (image != null) {\r
78                     images.put(imageDescriptor, image);\r
79                 }\r
80             }\r
81         }\r
82 \r
83         locks.remove(imageDescriptor, loadLock);\r
84 \r
85         return image;\r
86     }\r
87 \r
88     public void dispose() {\r
89         // Do not synchronize while disposing image resources\r
90         Image[] imgs = null;\r
91         synchronized (images) {\r
92             imgs = images.values().toArray(new Image[images.size()]);\r
93             images.clear();\r
94         }\r
95         locks.clear();\r
96 \r
97         for (Image img : imgs) {\r
98             img.dispose();\r
99         }\r
100     }\r
101 \r
102     public static ImageCache getInstance() {\r
103         return imageCache;\r
104     }\r
105 \r
106 }\r