1 | static class ScalablePane extends JPanel { |
2 | |
3 | private Image master; |
4 | private boolean toFit; |
5 | private Image scaled; |
6 | |
7 | public ScalablePane(Image master) { |
8 | this(master, true); |
9 | } |
10 | |
11 | public ScalablePane(Image master, boolean toFit) { |
12 | this.master = master; |
13 | setToFit(toFit); |
14 | } |
15 | |
16 | @Override |
17 | public Dimension getPreferredSize() { |
18 | return master == null ? super.getPreferredSize() : new Dimension(master.getWidth(this), master.getHeight(this)); |
19 | } |
20 | |
21 | @Override |
22 | protected void paintComponent(Graphics g) { |
23 | super.paintComponent(g); |
24 | Image toDraw = null; |
25 | if (scaled != null) { |
26 | toDraw = scaled; |
27 | } else if (master != null) { |
28 | toDraw = master; |
29 | } |
30 | |
31 | if (toDraw != null) { |
32 | int x = (getWidth() - toDraw.getWidth(this)) / 2; |
33 | int y = (getHeight() - toDraw.getHeight(this)) / 2; |
34 | g.drawImage(toDraw, x, y, this); |
35 | } |
36 | } |
37 | |
38 | @Override |
39 | public void invalidate() { |
40 | generateScaledInstance(); |
41 | super.invalidate(); |
42 | } |
43 | |
44 | public boolean isToFit() { |
45 | return toFit; |
46 | } |
47 | |
48 | public void setToFit(boolean value) { |
49 | if (value != toFit) { |
50 | toFit = value; |
51 | invalidate(); |
52 | } |
53 | } |
54 | |
55 | protected void generateScaledInstance() { |
56 | scaled = null; |
57 | if (isToFit()) { |
58 | scaled = getScaledInstanceToFit(master, getSize()); |
59 | } else { |
60 | scaled = getScaledInstanceToFill(master, getSize()); |
61 | } |
62 | } |
63 | |
64 | protected BufferedImage toBufferedImage(Image master) { |
65 | Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this)); |
66 | BufferedImage image = createCompatibleImage(masterSize); |
67 | Graphics2D g2d = image.createGraphics(); |
68 | g2d.drawImage(master, 0, 0, this); |
69 | g2d.dispose(); |
70 | return image; |
71 | } |
72 | |
73 | public Image getScaledInstanceToFit(Image master, Dimension size) { |
74 | Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this)); |
75 | return getScaledInstance( |
76 | toBufferedImage(master), |
77 | getScaleFactorToFit(masterSize, size), |
78 | RenderingHints.VALUE_INTERPOLATION_BILINEAR, |
79 | true); |
80 | } |
81 | |
82 | public Image getScaledInstanceToFill(Image master, Dimension size) { |
83 | Dimension masterSize = new Dimension(master.getWidth(this), master.getHeight(this)); |
84 | return getScaledInstance( |
85 | toBufferedImage(master), |
86 | getScaleFactorToFill(masterSize, size), |
87 | RenderingHints.VALUE_INTERPOLATION_BILINEAR, |
88 | true); |
89 | } |
90 | |
91 | public Dimension getSizeToFit(Dimension original, Dimension toFit) { |
92 | double factor = getScaleFactorToFit(original, toFit); |
93 | Dimension size = new Dimension(original); |
94 | size.width *= factor; |
95 | size.height *= factor; |
96 | return size; |
97 | } |
98 | |
99 | public Dimension getSizeToFill(Dimension original, Dimension toFit) { |
100 | double factor = getScaleFactorToFill(original, toFit); |
101 | Dimension size = new Dimension(original); |
102 | size.width *= factor; |
103 | size.height *= factor; |
104 | return size; |
105 | } |
106 | |
107 | public double getScaleFactor(int iMasterSize, int iTargetSize) { |
108 | return (double) iTargetSize / (double) iMasterSize; |
109 | } |
110 | |
111 | public double getScaleFactorToFit(Dimension original, Dimension toFit) { |
112 | double dScale = 1d; |
113 | if (original != null && toFit != null) { |
114 | double dScaleWidth = getScaleFactor(original.width, toFit.width); |
115 | double dScaleHeight = getScaleFactor(original.height, toFit.height); |
116 | dScale = Math.min(dScaleHeight, dScaleWidth); |
117 | } |
118 | return dScale; |
119 | } |
120 | |
121 | public double getScaleFactorToFill(Dimension masterSize, Dimension targetSize) { |
122 | double dScaleWidth = getScaleFactor(masterSize.width, targetSize.width); |
123 | double dScaleHeight = getScaleFactor(masterSize.height, targetSize.height); |
124 | |
125 | return Math.max(dScaleHeight, dScaleWidth); |
126 | } |
127 | |
128 | public BufferedImage createCompatibleImage(Dimension size) { |
129 | return createCompatibleImage(size.width, size.height); |
130 | } |
131 | |
132 | public BufferedImage createCompatibleImage(int width, int height) { |
133 | GraphicsConfiguration gc = getGraphicsConfiguration(); |
134 | if (gc == null) { |
135 | gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); |
136 | } |
137 | |
138 | BufferedImage image = gc.createCompatibleImage(width, height, Transparency.TRANSLUCENT); |
139 | image.coerceData(true); |
140 | return image; |
141 | } |
142 | |
143 | protected BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint, boolean bHighQuality) { |
144 | BufferedImage imgScale = img; |
145 | int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor); |
146 | int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor); |
147 | |
148 | if (dScaleFactor <= 1.0d) { |
149 | imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint, bHighQuality); |
150 | } else { |
151 | imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint, bHighQuality); |
152 | } |
153 | |
154 | return imgScale; |
155 | } |
156 | |
157 | protected BufferedImage getScaledDownInstance(BufferedImage img, |
158 | int targetWidth, |
159 | int targetHeight, |
160 | Object hint, |
161 | boolean higherQuality) { |
162 | |
163 | int type = (img.getTransparency() == Transparency.OPAQUE) |
164 | ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB; |
165 | |
166 | BufferedImage _ret = (BufferedImage) img; |
167 | |
168 | if (targetHeight > 0 || targetWidth > 0) { |
169 | int w, h; |
170 | if (higherQuality) { |
171 | // Use multi-step technique: start with original size, then |
172 | // scale down in multiple passes with drawImage() |
173 | // until the target size is reached |
174 | w = img.getWidth(); |
175 | h = img.getHeight(); |
176 | } else { |
177 | // Use one-step technique: scale directly from original |
178 | // size to target size with a single drawImage() call |
179 | w = targetWidth; |
180 | h = targetHeight; |
181 | } |
182 | |
183 | do { |
184 | if (higherQuality && w > targetWidth) { |
185 | w /= 2; |
186 | if (w < targetWidth) { |
187 | w = targetWidth; |
188 | } |
189 | } |
190 | if (higherQuality && h > targetHeight) { |
191 | h /= 2; |
192 | if (h < targetHeight) { |
193 | h = targetHeight; |
194 | } |
195 | } |
196 | |
197 | BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type); |
198 | Graphics2D g2 = tmp.createGraphics(); |
199 | g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); |
200 | g2.drawImage(_ret, 0, 0, w, h, null); |
201 | g2.dispose(); |
202 | |
203 | _ret = tmp; |
204 | } while (w != targetWidth || h != targetHeight); |
205 | } else { |
206 | _ret = new BufferedImage(1, 1, type); |
207 | } |
208 | |
209 | return _ret; |
210 | } |
211 | |
212 | protected BufferedImage getScaledUpInstance(BufferedImage img, |
213 | int targetWidth, |
214 | int targetHeight, |
215 | Object hint, |
216 | boolean higherQuality) { |
217 | |
218 | int type = BufferedImage.TYPE_INT_ARGB; |
219 | |
220 | BufferedImage _ret = (BufferedImage) img; |
221 | int w, h; |
222 | if (higherQuality) { |
223 | // Use multi-step technique: start with original size, then |
224 | // scale down in multiple passes with drawImage() |
225 | // until the target size is reached |
226 | w = img.getWidth(); |
227 | h = img.getHeight(); |
228 | } else { |
229 | // Use one-step technique: scale directly from original |
230 | // size to target size with a single drawImage() call |
231 | w = targetWidth; |
232 | h = targetHeight; |
233 | } |
234 | |
235 | do { |
236 | if (higherQuality && w < targetWidth) { |
237 | w *= 2; |
238 | if (w > targetWidth) { |
239 | w = targetWidth; |
240 | } |
241 | } |
242 | |
243 | if (higherQuality && h < targetHeight) { |
244 | h *= 2; |
245 | if (h > targetHeight) { |
246 | h = targetHeight; |
247 | } |
248 | } |
249 | |
250 | BufferedImage tmp = new BufferedImage(w, h, type); |
251 | Graphics2D g2 = tmp.createGraphics(); |
252 | g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint); |
253 | g2.drawImage(_ret, 0, 0, w, h, null); |
254 | g2.dispose(); |
255 | |
256 | _ret = tmp; |
257 | tmp = null; |
258 | } while (w != targetWidth || h != targetHeight); |
259 | return _ret; |
260 | } |
261 | } |
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1001014 |
Snippet name: | ScalablePane |
Eternal ID of this version: | #1001014/1 |
Text MD5: | d9f81057cc11368a2df72f9d1abc051c |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2015-09-16 01:45:33 |
Source code size: | 10088 bytes / 261 lines |
Pitched / IR pitched: | No / Yes |
Views / Downloads: | 579 / 950 |
Referenced in: | [show references] |