Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/swing/CachedPainter.java
38829 views
1
/*
2
* Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
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
48
* draw the image yourself. This is primarly useful when you are not
49
* using <code>VolatileImage</code>.
50
* </ol>
51
*
52
*
53
*/
54
public abstract class CachedPainter {
55
// CacheMap maps from class to ImageCache.
56
private static final Map<Object,ImageCache> cacheMap = new HashMap<>();
57
58
private static ImageCache getCache(Object key) {
59
synchronized(CachedPainter.class) {
60
ImageCache cache = cacheMap.get(key);
61
if (cache == null) {
62
cache = new ImageCache(1);
63
cacheMap.put(key, cache);
64
}
65
return cache;
66
}
67
}
68
69
/**
70
* Creates an instance of <code>CachedPainter</code> that will cache up
71
* to <code>cacheCount</code> images of this class.
72
*
73
* @param cacheCount Max number of images to cache
74
*/
75
public CachedPainter(int cacheCount) {
76
getCache(getClass()).setMaxCount(cacheCount);
77
}
78
79
/**
80
* Renders the cached image to the the passed in <code>Graphic</code>.
81
* If there is no cached image <code>paintToImage</code> will be invoked.
82
* <code>paintImage</code> is invoked to paint the cached image.
83
*
84
* @param c Component rendering to, this may be null.
85
* @param g Graphics to paint to
86
* @param x X-coordinate to render to
87
* @param y Y-coordinate to render to
88
* @param w Width to render in
89
* @param h Height to render in
90
* @param arg 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
153
* @param h Height to paint to
154
* @param args Arguments supplied to <code>paint</code>
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);
196
}
197
198
/**
199
* Clear the image cache
200
*/
201
protected void flush() {
202
synchronized(CachedPainter.class) {
203
getCache(getClass()).flush();
204
}
205
}
206
207
private GraphicsConfiguration getGraphicsConfiguration(Component c) {
208
if (c == null) {
209
return null;
210
}
211
return c.getGraphicsConfiguration();
212
}
213
}
214
215