8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package sun.swing;
26
27 import java.awt.*;
28 import java.awt.image.*;
29 import java.util.*;
30
31 /**
32 * A base class used for icons or images that are expensive to paint.
33 * A subclass will do the following:
34 * <ol>
35 * <li>Invoke <code>paint</code> when you want to paint the image,
36 * if you are implementing <code>Icon</code> you'll invoke this from
37 * <code>paintIcon</code>.
38 * The args argument is useful when additional state is needed.
39 * <li>Override <code>paintToImage</code> to render the image. The code that
40 * lives here is equivalent to what previously would go in
41 * <code>paintIcon</code>, for an <code>Icon</code>.
42 * </ol>
43 * The two ways to use this class are:
44 * <ol>
45 * <li>Invoke <code>paint</code> to draw the cached reprensentation at
46 * the specified location.
47 * <li>Invoke <code>getImage</code> to get the cached reprensentation and
87 * @param y Y-coordinate to render to
88 * @param w Width to render in
89 * @param h Height to render in
90 * @param args Variable arguments that will be passed to paintToImage
91 */
92 public void paint(Component c, Graphics g, int x,
93 int y, int w, int h, Object... args) {
94 if (w <= 0 || h <= 0) {
95 return;
96 }
97 synchronized (CachedPainter.class) {
98 paint0(c, g, x, y, w, h, args);
99 }
100 }
101
102 private void paint0(Component c, Graphics g, int x,
103 int y, int w, int h, Object... args) {
104 Object key = getClass();
105 GraphicsConfiguration config = getGraphicsConfiguration(c);
106 ImageCache cache = getCache(key);
107 Image image = cache.getImage(key, config, w, h, args);
108 int attempts = 0;
109 do {
110 boolean draw = false;
111 if (image instanceof VolatileImage) {
112 // See if we need to recreate the image
113 switch (((VolatileImage)image).validate(config)) {
114 case VolatileImage.IMAGE_INCOMPATIBLE:
115 ((VolatileImage)image).flush();
116 image = null;
117 break;
118 case VolatileImage.IMAGE_RESTORED:
119 draw = true;
120 break;
121 }
122 }
123 if (image == null) {
124 // Recreate the image
125 image = createImage(c, w, h, config, args);
126 cache.setImage(key, config, w, h, args, image);
127 draw = true;
128 }
129 if (draw) {
130 // Render to the Image
131 Graphics g2 = image.getGraphics();
132 paintToImage(c, image, g2, w, h, args);
133 g2.dispose();
134 }
135
136 // Render to the passed in Graphics
137 paintImage(c, g, x, y, w, h, image, args);
138
139 // If we did this 3 times and the contents are still lost
140 // assume we're painting to a VolatileImage that is bogus and
141 // give up. Presumably we'll be called again to paint.
142 } while ((image instanceof VolatileImage) &&
143 ((VolatileImage)image).contentsLost() && ++attempts < 3);
144 }
145
146 /**
147 * Paints the representation to cache to the supplied Graphics.
148 *
149 * @param c Component painting to, may be null.
150 * @param image Image to paint to
151 * @param g Graphics to paint to, obtained from the passed in Image.
152 * @param w Width to paint to
155 */
156 protected abstract void paintToImage(Component c, Image image, Graphics g,
157 int w, int h, Object[] args);
158
159
160 /**
161 * Paints the image to the specified location.
162 *
163 * @param c Component painting to
164 * @param g Graphics to paint to
165 * @param x X coordinate to paint to
166 * @param y Y coordinate to paint to
167 * @param w Width to paint to
168 * @param h Height to paint to
169 * @param image Image to paint
170 * @param args Arguments supplied to <code>paint</code>
171 */
172 protected void paintImage(Component c, Graphics g,
173 int x, int y, int w, int h, Image image,
174 Object[] args) {
175 g.drawImage(image, x, y, null);
176 }
177
178 /**
179 * Creates the image to cache. This returns an opaque image, subclasses
180 * that require translucency or transparency will need to override this
181 * method.
182 *
183 * @param c Component painting to
184 * @param w Width of image to create
185 * @param h Height to image to create
186 * @param config GraphicsConfiguration that will be
187 * rendered to, this may be null.
188 * @param args Arguments passed to paint
189 */
190 protected Image createImage(Component c, int w, int h,
191 GraphicsConfiguration config, Object[] args) {
192 if (config == null) {
193 return new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
194 }
195 return config.createCompatibleVolatileImage(w, h);
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package sun.swing;
26
27 import java.awt.*;
28 import java.awt.geom.AffineTransform;
29 import java.awt.image.*;
30 import java.util.*;
31
32 /**
33 * A base class used for icons or images that are expensive to paint.
34 * A subclass will do the following:
35 * <ol>
36 * <li>Invoke <code>paint</code> when you want to paint the image,
37 * if you are implementing <code>Icon</code> you'll invoke this from
38 * <code>paintIcon</code>.
39 * The args argument is useful when additional state is needed.
40 * <li>Override <code>paintToImage</code> to render the image. The code that
41 * lives here is equivalent to what previously would go in
42 * <code>paintIcon</code>, for an <code>Icon</code>.
43 * </ol>
44 * The two ways to use this class are:
45 * <ol>
46 * <li>Invoke <code>paint</code> to draw the cached reprensentation at
47 * the specified location.
48 * <li>Invoke <code>getImage</code> to get the cached reprensentation and
88 * @param y Y-coordinate to render to
89 * @param w Width to render in
90 * @param h Height to render in
91 * @param args Variable arguments that will be passed to paintToImage
92 */
93 public void paint(Component c, Graphics g, int x,
94 int y, int w, int h, Object... args) {
95 if (w <= 0 || h <= 0) {
96 return;
97 }
98 synchronized (CachedPainter.class) {
99 paint0(c, g, x, y, w, h, args);
100 }
101 }
102
103 private void paint0(Component c, Graphics g, int x,
104 int y, int w, int h, Object... args) {
105 Object key = getClass();
106 GraphicsConfiguration config = getGraphicsConfiguration(c);
107 ImageCache cache = getCache(key);
108
109 AffineTransform tx = ((Graphics2D) g).getTransform();
110 int sw = tx.isIdentity() ? w : (int) Math.round(w * tx.getScaleX());
111 int sh = tx.isIdentity() ? h : (int) Math.round(h * tx.getScaleY());
112
113 Image image = cache.getImage(key, config, sw, sh, args);
114 int attempts = 0;
115 do {
116 boolean draw = false;
117 if (image instanceof VolatileImage) {
118 // See if we need to recreate the image
119 switch (((VolatileImage)image).validate(config)) {
120 case VolatileImage.IMAGE_INCOMPATIBLE:
121 ((VolatileImage)image).flush();
122 image = null;
123 break;
124 case VolatileImage.IMAGE_RESTORED:
125 draw = true;
126 break;
127 }
128 }
129 if (image == null) {
130 // Recreate the image
131 image = createImage(c, sw, sh, config, args);
132 cache.setImage(key, config, sw, sh, args, image);
133 draw = true;
134 }
135 if (draw) {
136 // Render to the Image
137 Graphics g2 = image.getGraphics();
138 paintToImage(c, image, g2, sw, sh, args);
139 g2.dispose();
140 }
141
142 // Render to the passed in Graphics
143 paintImage(c, g, x, y, w, h, image, args);
144
145 // If we did this 3 times and the contents are still lost
146 // assume we're painting to a VolatileImage that is bogus and
147 // give up. Presumably we'll be called again to paint.
148 } while ((image instanceof VolatileImage) &&
149 ((VolatileImage)image).contentsLost() && ++attempts < 3);
150 }
151
152 /**
153 * Paints the representation to cache to the supplied Graphics.
154 *
155 * @param c Component painting to, may be null.
156 * @param image Image to paint to
157 * @param g Graphics to paint to, obtained from the passed in Image.
158 * @param w Width to paint to
161 */
162 protected abstract void paintToImage(Component c, Image image, Graphics g,
163 int w, int h, Object[] args);
164
165
166 /**
167 * Paints the image to the specified location.
168 *
169 * @param c Component painting to
170 * @param g Graphics to paint to
171 * @param x X coordinate to paint to
172 * @param y Y coordinate to paint to
173 * @param w Width to paint to
174 * @param h Height to paint to
175 * @param image Image to paint
176 * @param args Arguments supplied to <code>paint</code>
177 */
178 protected void paintImage(Component c, Graphics g,
179 int x, int y, int w, int h, Image image,
180 Object[] args) {
181 g.drawImage(image, x, y, w, h, null);
182 }
183
184 /**
185 * Creates the image to cache. This returns an opaque image, subclasses
186 * that require translucency or transparency will need to override this
187 * method.
188 *
189 * @param c Component painting to
190 * @param w Width of image to create
191 * @param h Height to image to create
192 * @param config GraphicsConfiguration that will be
193 * rendered to, this may be null.
194 * @param args Arguments passed to paint
195 */
196 protected Image createImage(Component c, int w, int h,
197 GraphicsConfiguration config, Object[] args) {
198 if (config == null) {
199 return new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
200 }
201 return config.createCompatibleVolatileImage(w, h);
|