/** * Copyright (c) 2004-2006 Regents of the University of California. * See "license-prefuse.txt" for licensing terms. */ package prefuse.util.display; import java.awt.Container; import java.awt.Graphics2D; import java.awt.Image; import java.awt.MediaTracker; import java.awt.Toolkit; import java.awt.geom.AffineTransform; import java.net.URL; import prefuse.Display; import prefuse.util.io.IOLib; /** * Paints a background image in a display. The image can either pan and zoom * along with the display or stay stationary. Additionally, the image can * be optionally tiled across the Display space. This class is used by * the {@link prefuse.Display} class in response to the * {@link prefuse.Display#setBackgroundImage(Image, boolean, boolean)} and * {@link prefuse.Display#setBackgroundImage(String, boolean, boolean)} * methods. * * @author jeffrey heer */ public class BackgroundPainter implements PaintListener { private static final double THRESH = 0.01; private Image m_img; private boolean m_fixed; private boolean m_tiled; private AffineTransform m_identity; private Clip m_clip; /** * Create a new BackgroundPainter. * @param imageLocation a location String of where to retrieve the * image file from. Uses * {@link prefuse.util.io.IOLib#urlFromString(String)} to resolve * the String. * @param fixed true if the background image should stay in a fixed * position, invariant to panning, zooming, or rotation; false if * the image should be subject to view transforms * @param tile true to tile the image across the visible background, * false to only include the image once */ public BackgroundPainter(String imageLocation, boolean fixed, boolean tile) { URL url = IOLib.urlFromString(imageLocation); m_img = Toolkit.getDefaultToolkit().getImage(url); MediaTracker mt = new MediaTracker(new Container()); mt.addImage(m_img, 0); try { mt.waitForID(0); } catch ( Exception e ) { e.printStackTrace(); } mt.removeImage(m_img, 0); m_fixed = fixed; m_tiled = tile; } /** * Create a new BackgroundPainter. * @param image the background Image * @param fixed true if the background image should stay in a fixed * position, invariant to panning, zooming, or rotation; false if * the image should be subject to view transforms * @param tile true to tile the image across the visible background, * false to only include the image once */ public BackgroundPainter(Image image, boolean fixed, boolean tile) { m_img = image; m_fixed = fixed; m_tiled = tile; } /** * Paint the background. * @see prefuse.util.display.PaintListener#prePaint(prefuse.Display, java.awt.Graphics2D) */ public void prePaint(Display d, Graphics2D g) { AffineTransform at = g.getTransform(); boolean translate = isTranslation(at); if ( m_fixed || translate ) { // if the background is fixed, we can unset the transform. // if we have no scaling component, we draw the image directly // rather than run it through the transform. // this avoids rendering artifacts on Java 1.5 on Win32. int tx = m_fixed ? 0 : (int)at.getTranslateX(); int ty = m_fixed ? 0 : (int)at.getTranslateY(); g.setTransform(getIdentity()); if ( m_tiled ) { // if tiled, compute visible background region and draw tiles int w = d.getWidth(), iw = m_img.getWidth(null); int h = d.getHeight(), ih = m_img.getHeight(null); int sx = m_fixed ? 0 : tx%iw; int sy = m_fixed ? 0 : ty%ih; if ( sx > 0 ) sx -= iw; if ( sy > 0 ) sy -= ih; for ( int x=sx; x