001 package com.croftsoft.core.awt.image; 002 003 import java.awt.*; 004 import java.awt.image.BufferedImage; 005 import java.io.*; 006 import java.util.*; 007 008 import com.croftsoft.core.lang.ClassLib; 009 import com.croftsoft.core.lang.NullArgumentException; 010 011 /********************************************************************* 012 * Caches loaded images by file name. 013 * 014 * @version 015 * 2003-07-24 016 * @since 017 * 2002-02-05 018 * @author 019 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 020 *********************************************************************/ 021 022 public final class ImageCache 023 ////////////////////////////////////////////////////////////////////// 024 ////////////////////////////////////////////////////////////////////// 025 { 026 027 private final Map imageMap; 028 029 private final int transparency; 030 031 private final Component component; 032 033 private final ClassLoader classLoader; 034 035 private final String mediaDir; 036 037 ////////////////////////////////////////////////////////////////////// 038 // Constructor methods 039 ////////////////////////////////////////////////////////////////////// 040 041 /********************************************************************* 042 * Main constructor. 043 * 044 * @see 045 * java.util.WeakHashMap 046 * 047 * @param imageMap 048 * 049 * A Map of images keyed by filenames. You may wish to consider 050 * using a WeakHashMap instead of the default HashMap created by 051 * the convenience constructor. 052 *********************************************************************/ 053 public ImageCache ( 054 int transparency, 055 Component component, 056 ClassLoader classLoader, 057 String mediaDir, 058 Map imageMap ) 059 ////////////////////////////////////////////////////////////////////// 060 { 061 this.transparency = transparency; 062 063 this.component = component; 064 065 this.classLoader = classLoader; 066 067 this.mediaDir = mediaDir; 068 069 NullArgumentException.check ( this.imageMap = imageMap ); 070 } 071 072 public ImageCache ( 073 int transparency, 074 Component component, 075 ClassLoader classLoader, 076 String mediaDir ) 077 ////////////////////////////////////////////////////////////////////// 078 { 079 this ( transparency, component, classLoader, mediaDir, 080 new HashMap ( ) ); 081 } 082 083 /********************************************************************* 084 * Convenience constructor. 085 *********************************************************************/ 086 public ImageCache ( Map imageMap ) 087 ////////////////////////////////////////////////////////////////////// 088 { 089 this ( 090 0, 091 ( Component ) null, 092 ( ClassLoader ) null, 093 ( String ) null, 094 imageMap ); 095 } 096 097 /********************************************************************* 098 * Convenience constructor. 099 * 100 * this(new HashMap()); 101 *********************************************************************/ 102 public ImageCache ( ) 103 ////////////////////////////////////////////////////////////////////// 104 { 105 this ( new HashMap ( ) ); 106 } 107 108 ////////////////////////////////////////////////////////////////////// 109 ////////////////////////////////////////////////////////////////////// 110 111 public void clear ( ) 112 ////////////////////////////////////////////////////////////////////// 113 { 114 imageMap.clear ( ); 115 } 116 117 public boolean containsKey ( String imageFilename ) 118 ////////////////////////////////////////////////////////////////////// 119 { 120 return imageMap.containsKey ( imageFilename ); 121 } 122 123 public BufferedImage get ( String imageFilename ) 124 throws IOException 125 ////////////////////////////////////////////////////////////////////// 126 { 127 BufferedImage image 128 = ( BufferedImage ) imageMap.get ( imageFilename ); 129 130 if ( ( image == null ) 131 && ( component != null ) 132 && ( classLoader != null ) ) 133 { 134 image = ImageLib.loadAutomaticImage ( 135 mediaDir == null ? imageFilename : mediaDir + imageFilename, 136 transparency, 137 component, 138 classLoader, 139 ( Dimension ) null ); 140 141 imageMap.put ( imageFilename, image ); 142 } 143 144 return image; 145 } 146 147 public Image remove ( String imageFilename ) 148 ////////////////////////////////////////////////////////////////////// 149 { 150 return ( Image ) imageMap.remove ( imageFilename ); 151 } 152 153 /********************************************************************* 154 * Validates the image. 155 * 156 * <p> 157 * Checks to see if the image is already loaded. If not, loads the 158 * file as a class resource byte stream and converts to an image. 159 * If component is not null, creates a MediaTracker to wait until the 160 * image is completely loaded before returning. 161 * </p> 162 * 163 * @see 164 * java.awt.MediaTracker 165 * 166 * @see 167 * com.croftsoft.core.lang.ClassLib#getResourceAsImage 168 * 169 * @param imageFilename 170 * 171 * The image filename and cache key. Filenames are relative to 172 * the root of the classpath or JAR file. 173 * Example: if the classpath is "J:\lib", this method would load 174 * "/images/image.png" from "J:\lib\images\image.png". 175 * 176 * @param component 177 * 178 * If null, a MediaTracker will not be used to ensure load completion 179 * before returning. 180 * 181 * @param maxWaitTimeMs 182 * 183 * The maximum time in milliseconds to wait for an image to finish 184 * loading before returning. Passed as the argument to 185 * MediaTracker.waitForAll(). 186 *********************************************************************/ 187 public Image validate ( 188 String imageFilename, 189 Component component, 190 long maxWaitTimeMs ) 191 throws IOException, InterruptedException 192 ////////////////////////////////////////////////////////////////////// 193 { 194 Image image = ( Image ) imageMap.get ( imageFilename ); 195 196 if ( image == null ) 197 { 198 image = ClassLib.getResourceAsImage ( 199 ImageCache.class, imageFilename ); 200 201 imageMap.put ( imageFilename, image ); 202 203 if ( component != null ) 204 { 205 MediaTracker mediaTracker = new MediaTracker ( component ); 206 207 mediaTracker.addImage ( image, 0 ); 208 209 mediaTracker.waitForAll ( maxWaitTimeMs ); 210 } 211 } 212 213 return image; 214 } 215 216 /********************************************************************* 217 * Validates the image without waiting to ensure load completion. 218 * 219 * Calls <code>validate(imageFilename,null,0)</code>. 220 *********************************************************************/ 221 public Image validate ( String imageFilename ) 222 throws IOException 223 ////////////////////////////////////////////////////////////////////// 224 { 225 Image image = null; 226 227 try 228 { 229 image = validate ( imageFilename, null, 0 ); 230 } 231 catch ( InterruptedException ex ) 232 { 233 // This code should never happen. 234 235 ex.printStackTrace ( ); 236 } 237 238 return image; 239 } 240 241 ////////////////////////////////////////////////////////////////////// 242 ////////////////////////////////////////////////////////////////////// 243 }