001    /*
002     * ToolkitLoader
003     * 
004     * Copyright (c) 2000, 2001, 2002, 2003 Marco Schmidt.
005     * All rights reserved.
006     */
007    
008    package net.sourceforge.jiu.gui.awt;
009    
010    import java.awt.Frame;
011    import java.awt.Image;
012    import java.awt.MediaTracker;
013    import java.awt.Toolkit;
014    import java.io.IOException;
015    import java.util.Vector;
016    import net.sourceforge.jiu.codecs.ImageLoader;
017    import net.sourceforge.jiu.data.PixelImage;
018    import net.sourceforge.jiu.data.RGB24Image;
019    import net.sourceforge.jiu.gui.awt.ImageCreator;
020    import net.sourceforge.jiu.ops.OperationFailedException;
021    
022    /**
023     * This class loads an instance of {@link java.awt.Image} using
024     * {@link java.awt.Toolkit}'s built-in loading capabilities and 
025     * converts it to {@link net.sourceforge.jiu.data.RGB24Image} using
026     * {@link net.sourceforge.jiu.gui.awt.ImageCreator}.
027     * <p>
028     * Supported file formats are JPEG and GIF.
029     * PNG is supported since Java 1.3.
030     * I have heard that XBM are supposedly loaded as well.
031     * I don't know that format and haven't tested this functionality.
032     * <p>
033     * In addition, this class can also use JIU's built-in codecs from
034     * this class.
035     * <h3>Usage examples</h3>
036     * Load an image using Java's own {@link java.awt.Toolkit} class:
037     * <pre>
038     * RGB24Image rgbImage = ToolkitLoader.loadAsRgb24Image("flower.jpg");
039     * </pre>
040     * This will only load images from files in formats that are supported
041     * by Toolkit - normally, that only includes JPEG, GIF and since Java 1.3 PNG.
042     * A potential problem of this approach is that Toolkit always delivers RGB
043     * data, even if the image file only contains a black and white image.
044     * In order to get an image object of the "real" type, try
045     * JIU's {@link net.sourceforge.jiu.color.reduction.AutoDetectColorType} with
046     * <code>rgbImage</code> (if you follow the link you will get a usage example
047     * for that class as well).
048     *
049     * <h3>Known issues</h3>
050     * If you are using this class to load JPEGs, GIFs or PNGs,
051     * an AWT background thread is started (as for a normal AWT GUI application).
052     * Before Java 1.4 there was a bug that kept the thread running although
053     * an application had reached the end of its execution (by getting to the
054     * end of the main(String[]) method).
055     * If you experience this problem, either update to a 1.4+ JDK or
056     * follow the advice given at <a href="http://www.jguru.com/faq/view.jsp?EID=467061" target="_top">jguru.com</a>
057     * and call <code>System.exit(0);</code>.
058     * @author Marco Schmidt
059     */
060    public class ToolkitLoader
061    {
062            private static Frame frame = null;
063    
064            /**
065             * This class has only static methods and fields, so there is no need to instantiate it.
066             * That's why the empty constructor is hidden here.
067             */
068            private ToolkitLoader()
069            {
070            }
071    
072            /**
073             * Loads an image from a file using the AWT's built-in loader.
074             * Returns that image as an AWT {@link java.awt.Image} object.
075             * This method does nothing more than call {@link java.awt.Toolkit#getImage(String)},
076             * wait for it using a {@link java.awt.MediaTracker} and return
077             * the resulting image.
078             *
079             * @param fileName name of the image file
080             * @return the image as AWT image object
081             */
082            public static Image load(String fileName)
083            {
084                    Toolkit toolkit = Toolkit.getDefaultToolkit();
085                    Image image = toolkit.getImage(fileName);
086                    if (frame == null)
087                    {
088                            frame = new Frame();
089                    }
090                    MediaTracker mt = new MediaTracker(frame);
091                    mt.addImage(image, 0);
092                    try
093                    {
094                            mt.waitForID(0);
095                    }
096                    catch (InterruptedException e)
097                    {
098                            return null;
099                    }
100                    return image;
101            }
102    
103            /**
104             * Loads an image from a file using the AWT's built-in loader and
105             * converts the image to a {@link net.sourceforge.jiu.data.RGB24Image}
106             * object.
107             * First calls {@link #load} with the filename, then converts 
108             * the loaded image using {@link ImageCreator#convertImageToRGB24Image}.
109             * @param fileName name of the file from which the image is to be loaded
110             * @return loaded image as {@link net.sourceforge.jiu.data.RGB24Image}
111             */
112            public static RGB24Image loadAsRgb24Image(String fileName)
113            {
114                    return ImageCreator.convertImageToRGB24Image(load(fileName));
115            }
116    
117            /**
118             * Attempts to load an image from a file given by its name,
119             * using both the JIU codecs and the image loading functionality in
120             * java.awt.Toolkit.
121             * First tries JIU's codecs, then java.awt.Toolkit.
122             * Simply calls <code>loadViaToolkitOrCodecs(fileName, false);</code>.
123             * @param fileName name of the image file
124             * @return image object or <code>null</code> on failure
125             */
126            public static PixelImage loadViaToolkitOrCodecs(String fileName)
127            {
128                    return loadViaToolkitOrCodecs(fileName, false, null);
129            }
130    
131            /**
132             * Attempts to load an image from a file given by its name,
133             * using both the JIU codecs and the image loading functionality in
134             * java.awt.Toolkit.
135             * The second argument determines which method is tried first,
136             * Toolkit (true) or the JIU codecs (false).
137             * Uses {@link #loadAsRgb24Image} from this class for Toolkit loading
138             * and {@link net.sourceforge.jiu.codecs.ImageLoader} for JIU's codecs.
139             * @param fileName name of the image file
140             * @return image object or <code>null</code> on failure
141             */
142            public static PixelImage loadViaToolkitOrCodecs(String fileName, boolean preferToolkit, Vector progressListeners)
143            {
144                    PixelImage result = null;
145                    try
146                    {
147                            if (preferToolkit)
148                            {
149                                    result = loadAsRgb24Image(fileName);
150                                    if (result == null)
151                                    {
152                                            result = ImageLoader.load(fileName, progressListeners);
153                                    }
154                            }
155                            else
156                            {
157                                    result = ImageLoader.load(fileName, progressListeners);
158                                    if (result == null)
159                                    {
160                                            result = loadAsRgb24Image(fileName);
161                                    }
162                            }
163                    }
164                    catch (OperationFailedException ofe)
165                    {
166                    }
167                    catch (IOException ioe)
168                    {
169                    }
170                    return result;
171            }
172    }