/* * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. */ import java.awt.*; import java.awt.image.*; import java.io.*; /** * Displays a single BufferedImage, scaled to fit the * paintFill rectangle. *
 *  BufferedImage image = ImageIO.read(new File("background.jpg"));
 *  final ImageFill imageFill = new ImageFill(image);
 *  JPanel p = new JPanel() {
 *      public c void paintComponent(Graphics g) {
 *	    imageFill.paintFill(this, g);
 *	}
 *  };
 * 
* Note that animated gifs aren't supported as there's no image observer. */ public class ImageFill extends Fill { private final static int IMAGE_CACHE_SIZE = 8; private BufferedImage image; private BufferedImage[] imageCache = new BufferedImage[IMAGE_CACHE_SIZE]; private int imageCacheIndex = 0; /** * Creates an ImageFill that draws image * scaled to fit the paintFill rectangle * parameters. * * @see #getImage * @see #paintFill */ public ImageFill(BufferedImage image) { this.image = image; } /** * Creates an "empty" ImageFill. Before the ImageFill can be * drawn with the paintFill method, the * image property must be set. * * @see #setImage * @see #paintFill */ public ImageFill() { this.image = null; } /** * Returns the image that the paintFill method draws. * * @return the value of the image property * @see #setImage * @see #paintFill */ public BufferedImage getImage() { return image; } /** * Set the image that the paintFill method draws. * * @param image the new value of the image property * @see #getImage * @see #paintFill */ public void setImage(BufferedImage image) { this.image = image; for(int i = 0; i < imageCache.length; i++) { imageCache[i] = null; } } /** * Returns the actual width of the BufferedImage * rendered by the paintFill method. If the image * property hasn't been set, -1 is returned. * * @return the value of getImage().getWidth() or -1 if * getImage() returns null * @see #getHeight * @see #setImage */ public int getWidth() { BufferedImage image = getImage(); return (image == null) ? -1 : image.getWidth(); } /** * Returns the actual height of the BufferedImage * rendered by the paintFill method. If the image * property hasn't been set, -1 is returned. * * @return the value of getImage().getHeight() or -1 if * getImage() returns null * @see #getWidth * @see #setImage */ public int getHeight() { BufferedImage image = getImage(); return (image == null) ? -1 : image.getHeight(); } /** * Create a copy of image scaled to width,height w,h and * add it to the null element of the imageCache array. If * the imageCache array is full, then we replace the "least * recently used element", at imageCacheIndex. */ private BufferedImage createScaledImage(Component c, int w, int h) { GraphicsConfiguration gc = c.getGraphicsConfiguration(); BufferedImage newImage = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT); boolean cacheOverflow = true; for(int i = 0; i < imageCache.length; i++) { Image image = imageCache[i]; if (image == null) { imageCache[i] = newImage; cacheOverflow = false; break; } } if (cacheOverflow) { imageCache[imageCacheIndex] = newImage; imageCacheIndex = (imageCacheIndex + 1) % imageCache.length; } Graphics g = newImage.getGraphics(); int width = image.getWidth(); int height = image.getHeight(); g.drawImage(image, 0, 0, w, h, 0, 0, width, height, null); g.dispose(); return newImage; } /** * Returns either the image itself or a cached scaled copy. */ private BufferedImage getFillImage(Component c, int w, int h) { if ((w == getWidth()) && (h == getHeight())) { return image; } for(int i = 0; i < imageCache.length; i++) { BufferedImage cimage = imageCache[i]; if (cimage == null) { break; } if ((cimage.getWidth(c) == w) && (cimage.getHeight(c) == h)) { return cimage; } } return createScaledImage(c, w, h); } /** * Draw the image at r.x,r.y, scaled to r.width * and r.height. */ public void paintFill(Component c, Graphics g, Rectangle r) { if ((r.width > 0) && (r.height > 0)) { BufferedImage fillImage = getFillImage(c, r.width, r.height); g.drawImage(fillImage, r.x, r.y, c); } } }