KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > util > display > BackgroundPainter


1 /**
2  * Copyright (c) 2004-2006 Regents of the University of California.
3  * See "license-prefuse.txt" for licensing terms.
4  */

5 package prefuse.util.display;
6
7 import java.awt.Container JavaDoc;
8 import java.awt.Graphics2D JavaDoc;
9 import java.awt.Image JavaDoc;
10 import java.awt.MediaTracker JavaDoc;
11 import java.awt.Toolkit JavaDoc;
12 import java.awt.geom.AffineTransform JavaDoc;
13
14 import prefuse.Display;
15 import prefuse.util.io.IOLib;
16
17 /**
18  * Paints a background image in a display. The image can either pan and zoom
19  * along with the display or stay stationary. Additionally, the image can
20  * be optionally tiled across the Display space. This class is used by
21  * the {@link prefuse.Display} class in response to the
22  * {@link prefuse.Display#setBackgroundImage(Image, boolean, boolean)} and
23  * {@link prefuse.Display#setBackgroundImage(String, boolean, boolean)}
24  * methods.
25  *
26  * @author <a HREF="http://jheer.org">jeffrey heer</a>
27  */

28 public class BackgroundPainter implements PaintListener {
29
30     private static final double THRESH = 0.01;
31     
32     private Image JavaDoc m_img;
33     private boolean m_fixed;
34     private boolean m_tiled;
35     
36     private AffineTransform JavaDoc m_identity;
37     private Clip m_clip;
38
39     /**
40      * Create a new BackgroundPainter.
41      * @param imageLocation a location String of where to retrieve the
42      * image file from. Uses
43      * {@link prefuse.util.io.IOLib#urlFromString(String)} to resolve
44      * the String.
45      * @param fixed true if the background image should stay in a fixed
46      * position, invariant to panning, zooming, or rotation; false if
47      * the image should be subject to view transforms
48      * @param tile true to tile the image across the visible background,
49      * false to only include the image once
50      */

51     public BackgroundPainter(String JavaDoc imageLocation, boolean fixed, boolean tile)
52     {
53         this(Toolkit.getDefaultToolkit()
54                 .getImage(IOLib.urlFromString(imageLocation)),
55              fixed, tile);
56     }
57     
58     /**
59      * Create a new BackgroundPainter.
60      * @param image the background Image
61      * @param fixed true if the background image should stay in a fixed
62      * position, invariant to panning, zooming, or rotation; false if
63      * the image should be subject to view transforms
64      * @param tile true to tile the image across the visible background,
65      * false to only include the image once
66      */

67     public BackgroundPainter(Image JavaDoc image, boolean fixed, boolean tile) {
68         m_img = image;
69         
70         // make sure the image is completely loaded
71
MediaTracker JavaDoc mt = new MediaTracker JavaDoc(new Container JavaDoc());
72         mt.addImage(m_img, 0);
73         try {
74             mt.waitForID(0);
75         } catch ( Exception JavaDoc e ) { e.printStackTrace(); }
76         mt.removeImage(m_img, 0);
77         
78         m_fixed = fixed;
79         m_tiled = tile;
80     }
81     
82     /**
83      * Paint the background.
84      * @see prefuse.util.display.PaintListener#prePaint(prefuse.Display, java.awt.Graphics2D)
85      */

86     public void prePaint(Display d, Graphics2D JavaDoc g) {
87         AffineTransform JavaDoc at = g.getTransform();
88         boolean translate = isTranslation(at);
89         
90         if ( m_fixed || translate )
91         {
92             // if the background is fixed, we can unset the transform.
93
// if we have no scaling component, we draw the image directly
94
// rather than run it through the transform.
95
// this avoids rendering artifacts on Java 1.5 on Win32.
96

97             int tx = m_fixed ? 0 : (int)at.getTranslateX();
98             int ty = m_fixed ? 0 : (int)at.getTranslateY();
99             
100             g.setTransform(getIdentity());
101             if ( m_tiled ) {
102                 // if tiled, compute visible background region and draw tiles
103
int w = d.getWidth(), iw = m_img.getWidth(null);
104                 int h = d.getHeight(), ih = m_img.getHeight(null);
105                 
106                 int sx = m_fixed ? 0 : tx%iw;
107                 int sy = m_fixed ? 0 : ty%ih;
108                 if ( sx > 0 ) sx -= iw;
109                 if ( sy > 0 ) sy -= ih;
110                 
111                 for ( int x=sx; x<w-sx; x+=iw ) {
112                     for ( int y=sy; y<h-sy; y+=ih )
113                         g.drawImage(m_img, x, y, null);
114                 }
115             } else {
116                 // if not tiled, simply draw the image at the translated origin
117
g.drawImage(m_img, tx, ty, null);
118             }
119             g.setTransform(at);
120         }
121         else
122         {
123             // run the image through the display transform
124
if ( m_tiled ) {
125                 int iw = m_img.getWidth(null);
126                 int ih = m_img.getHeight(null);
127                 
128                 // get the screen region and map it into item-space
129
Clip c = getClip();
130                 c.setClip(0, 0, d.getWidth(), d.getHeight());
131                 c.transform(d.getInverseTransform());
132                 
133                 // get the bounding region for image tiles
134
int w = (int)Math.ceil(c.getWidth());
135                 int h = (int)Math.ceil(c.getHeight());
136                 int tx = (int)c.getMinX();
137                 int ty = (int)c.getMinY();
138                 int dw = tx%iw + iw;
139                 int dh = ty%ih + ih;
140                 tx -= dw; w += dw;
141                 ty -= dh; h += dh;
142                 
143                 // draw the image tiles
144
for ( int x=tx; x<tx+w; x+=iw ) {
145                     for ( int y=ty; y<ty+h; y+=ih )
146                         g.drawImage(m_img, x, y, null);
147                 }
148             } else {
149                 // if not tiled, simply draw the image
150
g.drawImage(m_img, 0, 0, null);
151             }
152         }
153         
154     }
155
156     /**
157      * Check if the given AffineTransform is a translation
158      * (within thresholds -- see {@link #THRESH}.
159      */

160     private static boolean isTranslation(AffineTransform JavaDoc at) {
161         return ( Math.abs(at.getScaleX()-1.0) < THRESH &&
162                  Math.abs(at.getScaleY()-1.0) < THRESH &&
163                  Math.abs(at.getShearX()) < THRESH &&
164                  Math.abs(at.getShearY()) < THRESH );
165     }
166
167     /**
168      * Get an identity transform (creating it if necessary)
169      */

170     private AffineTransform JavaDoc getIdentity() {
171         if ( m_identity == null )
172             m_identity = new AffineTransform JavaDoc();
173         return m_identity;
174     }
175
176     /**
177      * Get a clip instance (creating it if necessary)
178      */

179     private Clip getClip() {
180         if ( m_clip == null )
181             m_clip = new Clip();
182         return m_clip;
183     }
184     
185     /**
186      * Does nothing.
187      * @see prefuse.util.display.PaintListener#postPaint(prefuse.Display, java.awt.Graphics2D)
188      */

189     public void postPaint(Display d, Graphics2D JavaDoc g) {
190         // do nothing
191
}
192
193 } // end of class BackgroundPainter
194
Popular Tags