package factory; import java.applet.*; import java.awt.*; import java.net.*; import java.util.*; /** A factory for loading images from the hard disk or web sites for use in * an applet or application. Uses flyweighting to cache identical images. * * @author Martin Stepp (stepp) */ public class ImageFactory { // private constructor to prohibit constructing factory private ImageFactory() {} /** The current running version of Java; used to discover capabilities. */ public static final double JAVA_VERSION = new Double(System.getProperty("java.version").substring(0, 3)).doubleValue(); private static final Hashtable imageHash = new Hashtable(); private static final boolean SHOULD_HASH = true; /** Makes and returns an image by loading it from the given file name. * In application context, this loads from the local disk. * In applet context, this treats fileName as a relative URL from the * applet's current code base URL directory. * * @param fileName the fully-qualified filename, or relatively qualified URL, * of the image resource to load. * @param comp the graphical component or applet responsible for tracking * the loading of this image. * * @return the successfully loaded Image object. */ public static Image createImage(String fileName, Component comp) { return createImage(fileName, null, comp); } /** Makes and returns an image by loading it from the given file name * within the given JAR archive. * In application context, this loads from the local disk. * In applet context, this treats fileName as a relative URL from the * applet's current code base URL directory. * * This method and its jarFileName option exists to permit * loading images from within a JAR; the method will construct a String * that represents the JAR path to the image, such as: *

   *  jar:file:/h:/java/myapplet/myapplet.jar!/images/someimage.gif
   *
   *  or
   *
   *  jar:http://www.mysite.com/myapplet/myapplet.jar!/images/someimage.gif
   *  
* * @param fileName the fully-qualified filename, or relatively qualified URL, * of the image resource to load. * @param comp the graphical component or applet responsible for tracking * the loading of this image. * If in applet context, the applet should be passed for this parameter. * @param jarFileName loads as though the fileName is in the given jar file. * Ignored if null is passed. * * @return the successfully loaded Image object. */ public static Image createImage(String fileName, String jarFileName, Component comp) { Image img = null; // look up previously loaded image if (SHOULD_HASH && imageHash.containsKey(fileName)) img = (Image)imageHash.get(fileName); // check legality of loading image from a JAR else if (JAVA_VERSION < 1.2 && jarFileName != null) throw new IllegalArgumentException("Can't load from a JAR in pre-v1.2 Java! " + "Current version is: " + JAVA_VERSION); // if an applet, load image from the web else { if (comp instanceof Applet) { Applet applet = (Applet) comp; URL codeBase = applet.getCodeBase(); if (codeBase == null) throw new IllegalArgumentException("Applet has null code base! \n\n" + "Don't load images in constructors; do all image-handling no \n" + "earlier than in the applet's init() method."); try { URL fileURL = (jarFileName != null) ? getJarFileURL(codeBase, jarFileName, fileName) : new URL(codeBase, fileName); img = applet.getImage(fileURL); } catch (MalformedURLException mfurle) { throw new IllegalArgumentException("Bad URL loading applet image from " + fileName + " : " + mfurle); } } // if not an applet, load image from a file else { Toolkit tk = Toolkit.getDefaultToolkit(); if (jarFileName != null) { // load from JAR as URL URL fileURL = getJarFileURL(System.getProperty("user.dir") + "/" + jarFileName, fileName); img = tk.getImage(fileURL); } else { // load as plain file img = tk.getImage(fileName); } } if (img == null) throw new IllegalArgumentException("Image was null; something must have gone wrong!"); // wait for image to load using MediaTracker MediaTracker mt = new MediaTracker(comp); mt.addImage(img, 0); try { mt.waitForID(0); } catch (InterruptedException ie) {} // check to see if image loaded properly if (img.getWidth(comp) == -1 || img.getHeight(comp) == -1) throw new IllegalArgumentException("No image was found in " + fileName); if (SHOULD_HASH) imageHash.put(fileName, img); } return img; } // returns URL of given file inside given JAR file, using given code base private static URL getJarFileURL(URL codeBase, String jarFileName, String fileName) { try { URL u = new URL("jar:" + codeBase + jarFileName + "!/" + fileName); return u; } catch (MalformedURLException mfurle) { throw new IllegalArgumentException(mfurle.toString()); } } // returns URL of given file inside given JAR file, making no assumptions // about code base (can pass a full path JAR file name) private static URL getJarFileURL(String jarFileName, String fileName) { try { URL u = new URL("jar:file:" + jarFileName + "!/" + fileName); return u; } catch (MalformedURLException mfurle) { throw new IllegalArgumentException(mfurle.toString()); } } }