View Javadoc
1   /*
2    * ThumbnailLoader.java
3    *
4    * Created on den 15 oktober 2002, 12:22
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          //Timer timer = new Timer();
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              //queueItem.getViewer().setImage( queueItem.getImageModel(), null );
76              queueItem.getViewer().setMessage( queueItem.getImageModel(), "Not enough memory" );
77          } 
78          catch ( IOException ioe )
79          {
80              //queueItem.getViewer().setImage( queueItem.getImageModel(), null );
81              queueItem.getViewer().setMessage( queueItem.getImageModel(), "Could not read image" );
82              System.err.println( ioe );
83          }
84          catch ( Throwable t )
85          {
86              //queueItem.getViewer().setImage( queueItem.getImageModel(), null );
87              queueItem.getViewer().setMessage( queueItem.getImageModel(), "Unexpected error while loading image" );
88              System.err.println( t );
89              t.printStackTrace();
90          }
91          //System.out.println( "loading" + panel.getData().getFilename() + "-" + timer );
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 }