1
2
3
4
5
6
7 package net.sourceforge.jsh3modtool.gui.imagetable.cache;
8
9 import java.awt.image.BufferedImage;
10 import java.io.IOException;
11 import java.util.Hashtable;
12 import java.util.Map;
13
14 import javax.imageio.ImageIO;
15
16 import net.sourceforge.jsh3modtool.gui.imagetable.ImageModel;
17
18 /***
19 * Thread to load thumbnails.
20 * To lessen the load of the thread that reads/creates ImageBoxes
21 *
22 * Singleton behaviour
23 *
24 * @author erma
25 */
26 public class ThumbnailLoader extends Thread
27 {
28 private static ThumbnailLoader loader;
29 private ThumbnailQueueItem activeItem;
30
31 private Map viewerLookupTable = new Hashtable();
32 private Map imagePropertiesLookupTable = new Hashtable();
33 private Queue queue = new Queue();
34
35 private boolean keepOnWaiting = true;
36
37 /***
38 * Creates a thumbnail loader.
39 */
40 protected ThumbnailLoader()
41 {
42 super("Thumbnail loader thread");
43 }
44
45 /***
46 * Returns the singleton instance of this class.
47 * @return the singleton instance.
48 */
49 public static ThumbnailLoader instance()
50 {
51 if ( loader== null )
52 {
53 loader = new ThumbnailLoader();
54 loader.setPriority( Thread.MIN_PRIORITY );
55 loader.startLoading();
56 }
57
58 return loader;
59 }
60
61 /***
62 * Loads the thumbnail for the panel.
63 * @param queueItem the queue item to load the thumbnail for.
64 */
65 private void loadThumbnail( ThumbnailQueueItem queueItem )
66 {
67
68 try
69 {
70 BufferedImage buffImage = ImageIO.read(queueItem.getImageModel().getData());
71 queueItem.getViewer().setImage( queueItem.getImageModel(), buffImage );
72 }
73 catch ( OutOfMemoryError oome )
74 {
75
76 queueItem.getViewer().setMessage( queueItem.getImageModel(), "Not enough memory" );
77 }
78 catch ( IOException ioe )
79 {
80
81 queueItem.getViewer().setMessage( queueItem.getImageModel(), "Could not read image" );
82 System.err.println( ioe );
83 }
84 catch ( Throwable t )
85 {
86
87 queueItem.getViewer().setMessage( queueItem.getImageModel(), "Unexpected error while loading image" );
88 System.err.println( t );
89 t.printStackTrace();
90 }
91
92 }
93
94 /***
95 * Thread run method, waits for items on the queue, removes it and reads the thumbnail
96 *for it and returns it to the listener
97 */
98 public void run()
99 {
100 keepOnWaiting = true;
101 while ( keepOnWaiting )
102 {
103 keepOnWaiting = queue.waitForFirstObject();
104 if ( keepOnWaiting )
105 {
106 ThumbnailQueueItem queueItem = (ThumbnailQueueItem) queue.removeFirst();
107
108 if ( queueItem != null )
109 {
110 activeItem = queueItem;
111 loadThumbnail( queueItem );
112 activeItem = null;
113
114 remove( queueItem );
115 }
116 }
117 }
118 }
119
120 /***
121 * Starts the Thumbnail loading thread (if it hasnt been started
122 */
123 public void startLoading()
124 {
125 if ( !isAlive() )
126 {
127 start();
128 }
129 }
130
131 /***
132 * Stops the Thumbnail loading thread, does not wait until the thread is dead
133 */
134 public void stopLoading()
135 {
136 keepOnWaiting = false;
137 interrupt();
138 }
139
140 /***
141 * Removes all ThumbnailViewers from the queue
142 */
143 public void clear()
144 {
145 queue.removeAll();
146 }
147
148 /***
149 * Add an ImageProperties and a ThumbnailViewer to the queue.
150 * @param imageProps the image props.
151 * @param viewer the viewer.
152 */
153 public void add( ImageModel imageProps, ThumbnailViewer viewer )
154 {
155 ThumbnailQueueItem item = new ThumbnailQueueItem( imageProps, viewer );
156 imagePropertiesLookupTable.put( imageProps, item );
157 viewerLookupTable.put( viewer, item );
158 queue.add( item );
159 }
160
161 /***
162 * Add an ImageProperties and a ThumbnailViewer to the the begining of the queue.
163 * @param imageProps the image props.
164 * @param viewer the viewer.
165 */
166 public void addFirst( ImageModel imageProps, ThumbnailViewer viewer )
167 {
168 ThumbnailQueueItem item = new ThumbnailQueueItem( imageProps, viewer );
169 imagePropertiesLookupTable.put( imageProps, item );
170 viewerLookupTable.put( viewer, item );
171 queue.addFirst( item );
172 }
173
174 /***
175 * Removes the first queue item.
176 */
177 public void removeFirst()
178 {
179 queue.removeFirst();
180 }
181
182 /***
183 * Removes the last queue item.
184 */
185 public void removeLast()
186 {
187 queue.removeLast();
188 }
189
190 /***
191 * Increase the priority of the specified item
192 * @param viewer the thumbnail viewer object to raise the priority for.
193 */
194 public void increasePriority( ThumbnailViewer viewer )
195 {
196 if ( ( activeItem == null ) || ( activeItem.getViewer() != viewer ) )
197 {
198 ThumbnailQueueItem item = (ThumbnailQueueItem) viewerLookupTable.get( viewer );
199 if ( item != null )
200 {
201 queue.remove( item );
202 queue.addFirst( item );
203 }
204 }
205 }
206
207 /***
208 * Increase the priority of the specified item.
209 * @param imageProps the image properties object to raise the priority for.
210 */
211 public void increasePriority( ImageModel imageProps )
212 {
213 if ( ( activeItem == null ) || ( activeItem.getImageModel() != imageProps ) )
214 {
215 ThumbnailQueueItem item = (ThumbnailQueueItem) imagePropertiesLookupTable.get( imageProps );
216 if ( item != null )
217 {
218 queue.remove( item );
219 queue.addFirst( item );
220 }
221 }
222 }
223
224 /***
225 * Returns true if the queue contains the specified object.
226 * @param imageProps the image properties to find.
227 * @return true if the queue contains the specified object.
228 */
229 public boolean contains( ImageModel imageProps )
230 {
231 return imagePropertiesLookupTable.containsKey( imageProps );
232 }
233
234 /***
235 * Returns the size of the queue. Note there may be one in the image handling
236 * method.
237 * @return the size of the queue.
238 */
239 public int queueSize()
240 {
241 return queue.size();
242 }
243
244 /***
245 * Removes the specified object from the queue.
246 * @param viewer the thumbnail viewer.
247 */
248 public void remove( ThumbnailViewer viewer )
249 {
250 ThumbnailQueueItem item = (ThumbnailQueueItem) viewerLookupTable.get( viewer );
251 if ( item != null )
252 {
253 queue.remove( item );
254 remove( item );
255 }
256 }
257
258 /***
259 * Removes the specified object from the queue.
260 * @param imageProps the image properties to remove.
261 */
262 public void remove( ImageModel imageProps )
263 {
264 ThumbnailQueueItem item = (ThumbnailQueueItem) imagePropertiesLookupTable.get( imageProps );
265 if ( item != null )
266 {
267 queue.remove( item );
268 remove( item );
269 }
270 }
271
272 /***
273 * Removes the specified object from the queue.
274 * @param item the queue item to remove.
275 */
276 private void remove( ThumbnailQueueItem item )
277 {
278 imagePropertiesLookupTable.remove( item.getImageModel() );
279 viewerLookupTable.remove( item.getViewer() );
280 }
281
282 /***
283 * A queue item that contains a viewer and a image properties object.
284 *
285 * @author erma
286 */
287 protected class ThumbnailQueueItem implements QueueItem
288 {
289 private ImageModel imageProperties;
290 private ThumbnailViewer thumbViewer;
291
292 /***
293 * Creates a queue item.
294 * @param imageProps the image properties.
295 * @param viewer the viewer.
296 */
297 public ThumbnailQueueItem(ImageModel imageProps, ThumbnailViewer viewer)
298 {
299 thumbViewer = viewer;
300 imageProperties = imageProps;
301 }
302
303 /***
304 * Returns the image properties for this queueitem.
305 * @return the image properties for this queueitem.
306 */
307 public ImageModel getImageModel()
308 {
309 return imageProperties;
310 }
311
312 /***
313 * Returns the viewer for this queueitem.
314 * @return the viewer for this queueitem.
315 */
316 public ThumbnailViewer getViewer()
317 {
318 return thumbViewer;
319 }
320 }
321 }