1 package net.sourceforge.jsh3modtool.gui.imagetable.cache;
2
3 import java.awt.Image;
4 import java.awt.image.BufferedImage;
5 import java.util.*;
6 import java.util.Map.Entry;
7
8 import net.sourceforge.jsh3modtool.gui.imagetable.ImageCell;
9 import net.sourceforge.jsh3modtool.gui.imagetable.ImageModel;
10
11 /***
12 * A very simple image cache stuff.
13 *
14 * @author erma
15 */
16 public class ImageCache implements ThumbnailViewer
17 {
18 private int loadingImagesMax = 50;
19 private Map loadingImagesLookupTable;
20 private ImageLoadingListener imageLoadingListener;
21
22 private int cachedImagesMax;
23 private int cachedImagesCount;
24 private Map cache;
25
26 /***
27 * Creates a new instance of ImageBrowserCache
28 * @param listener a image loading listener.
29 */
30 public ImageCache(ImageLoadingListener listener)
31 {
32 this( listener, 200 );
33 }
34
35 /***
36 * Creates a new instance of ImageBrowserCache
37 * @param listener a image loading listener.
38 * @param cacheMax the maximum number of images to cache.
39 */
40 public ImageCache(ImageLoadingListener listener, int cacheMax)
41 {
42 cachedImagesMax = cacheMax;
43 cache = Collections.synchronizedMap(new ImageCacheMap( cachedImagesMax, 0.75f ) );
44 loadingImagesLookupTable = Collections.synchronizedMap( new Hashtable() );
45 imageLoadingListener = listener;
46 }
47
48 /***
49 * Returns the number of cached images.
50 * @return the number of cached images.
51 */
52 public int getCachedImagesCount()
53 {
54 return cachedImagesCount;
55 }
56
57 /***
58 * Returns the cached image for the specified image, can be null.
59 * @param imageCell the image cell to get the cached image for.
60 * @return the cached image for the specified image, can be null.
61 */
62 public BufferedImage getImage( ImageCell imageCell )
63 {
64 BufferedImage image = null;
65 if ( imageCell != null )
66 {
67 image = (BufferedImage) cache.get( imageCell.getImageModel() );
68 if (( image == null ) && (!imageCell.hasTriedToLoadImage()))
69 {
70 loadTableImage( imageCell );
71 }
72 }
73 return image;
74 }
75
76 /***
77 * Loads the table image for thumbnailloader.
78 * @param imageCell the image cell to load an image for.
79 */
80 private void loadTableImage( ImageCell imageCell )
81 {
82 ImageModel imageModel = imageCell.getImageModel();
83 ThumbnailLoader loader = ThumbnailLoader.instance();
84
85 if ( ! loader.contains( imageModel ) )
86 {
87 loadingImagesLookupTable.put( imageModel, imageCell );
88 loader.addFirst( imageModel, this );
89
90 if ( loader.queueSize() > loadingImagesMax )
91 {
92 loader.removeLast();
93 }
94 }
95 else
96 {
97 loader.increasePriority( imageModel );
98 }
99 }
100
101 /***
102 * Tells the cache to reload the cached image.
103 * The cache will keep the old image until the new one has been loaded.
104 * When the new image has been loaded it will replace the cached and the
105 * cell with be updated.
106 * @param imageCell the cell that needs a new image.
107 */
108 public void reloadCachedImage( ImageCell imageCell )
109 {
110 loadTableImage( imageCell );
111 }
112
113 /***
114 * Returns if the tableimage is cached or not.
115 * @param imageCell the lookup object.
116 * @return if the tableimage is cached or not.
117 */
118 public boolean isCached( ImageCell imageCell )
119 {
120 return cache.containsKey(imageCell.getImageModel());
121 }
122
123 /***
124 * Clears the cache.
125 */
126 public void clear()
127 {
128 ThumbnailLoader.instance().clear();
129 cache.clear();
130 loadingImagesLookupTable.clear();
131 cachedImagesCount = 0;
132 }
133
134 /***
135 * Removes the cached images for the files in the list.
136 * @param files list containing File objects.
137 */
138
139
140
141
142
143
144
145
146
147 /***
148 * Clears the cached image from the cache.
149 * @param imageCell the image cells cached image to remove.
150 */
151 public void removeCachedImage( ImageCell imageCell )
152 {
153 cache.remove(imageCell.getImageModel());
154 }
155
156 /*** {@inheritDoc} */
157 private void cacheImage( ImageCell imageCell, Image image )
158 {
159 if ( ( imageCell.getImageModel() != null ) && ( image != null ) )
160 {
161 cache.put( imageCell.getImageModel(), image );
162 cachedImagesCount++;
163 }
164 imageLoadingListener.imageIsLoaded( imageCell );
165 }
166
167 /*** {@inheritDoc} */
168 public void setImage(ImageModel imageModel, Image image)
169 {
170 ImageCell imageCell = (ImageCell) loadingImagesLookupTable.get( imageModel );
171 loadingImagesLookupTable.remove( imageModel );
172
173 if ( imageCell != null )
174 {
175 cacheImage( imageCell, image );
176 }
177 }
178
179 /*** {@inheritDoc} */
180 public void setMessage(ImageModel imageModel, String msg)
181 {
182 ImageCell tableImage = (ImageCell) loadingImagesLookupTable.get( imageModel );
183
184 if ( tableImage != null )
185 {
186 loadingImagesLookupTable.remove( imageModel );
187 tableImage.setHasTriedToLoadImage( true );
188 tableImage.setErrorMessage( msg );
189 imageLoadingListener.imageIsLoaded( tableImage );
190 }
191 }
192
193 /***
194 * A linkedhashmap that removes the eldest entry if the size exceeds a number.
195 * @author erma
196 */
197 private class ImageCacheMap extends LinkedHashMap
198 {
199 /***
200 * Creates an ImageCacheMap with a set initialCapacity and loadFactor.
201 * @param initialCapacity the initial capacity.
202 * @param loadFactor the load factor.
203 */
204 protected ImageCacheMap(int initialCapacity, float loadFactor)
205 {
206 super(initialCapacity, loadFactor, true);
207 }
208
209 /*** {@inheritDoc} */
210 protected boolean removeEldestEntry(Entry eldest)
211 {
212 return size() > cachedImagesMax;
213 }
214 }
215 }