author | alexsch |
Tue, 15 Sep 2015 15:31:34 +0400 | |
changeset 32682 | 6f1200d8999d |
parent 27268 | 56ae490e62d2 |
child 40719 | 4ae72a69bd3b |
permissions | -rw-r--r-- |
12047 | 1 |
/* |
23649
f4f882f0056b
8035692: Fix serial lint warnings in mac-specific code
darcy
parents:
23328
diff
changeset
|
2 |
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. |
12047 | 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 |
||
26 |
package com.apple.laf; |
|
27 |
||
28 |
import java.awt.*; |
|
29 |
import java.awt.image.BufferedImage; |
|
30 |
import java.security.PrivilegedAction; |
|
31 |
||
32 |
import javax.swing.*; |
|
33 |
import javax.swing.plaf.*; |
|
34 |
||
35 |
import sun.lwawt.macosx.LWCToolkit; |
|
36 |
import apple.laf.JRSUIConstants.AlignmentHorizontal; |
|
37 |
import apple.laf.JRSUIConstants.AlignmentVertical; |
|
38 |
import apple.laf.JRSUIConstants.Direction; |
|
39 |
import apple.laf.JRSUIConstants.State; |
|
40 |
import apple.laf.JRSUIConstants.Widget; |
|
41 |
import apple.laf.*; |
|
42 |
||
43 |
import com.apple.eio.FileManager; |
|
44 |
import com.apple.laf.AquaIcon.InvertableIcon; |
|
45 |
import com.apple.laf.AquaIcon.JRSUIControlSpec; |
|
46 |
import com.apple.laf.AquaIcon.SystemIcon; |
|
47 |
import com.apple.laf.AquaUtils.RecyclableObject; |
|
48 |
import com.apple.laf.AquaUtils.RecyclableSingleton; |
|
32682
6f1200d8999d
8029339: Custom MultiResolution image support on HiDPI displays
alexsch
parents:
27268
diff
changeset
|
49 |
import java.awt.image.MultiResolutionImage; |
24532
24831bd48764
8040279: [macosx] Do not use the base image in the MultiResolutionBufferedImage
alexsch
parents:
23666
diff
changeset
|
50 |
import sun.awt.image.MultiResolutionCachedImage; |
12047 | 51 |
|
52 |
public class AquaImageFactory { |
|
53 |
public static IconUIResource getConfirmImageIcon() { |
|
54 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
55 |
||
56 |
return new IconUIResource(new AquaIcon.CachingScalingIcon(kAlertIconSize, kAlertIconSize) { |
|
57 |
Image createImage() { |
|
24533
7c429f6f88d2
7124250: [macosx] JOptionPane dialogs show wrong icons
pchelko
parents:
24532
diff
changeset
|
58 |
return getGenericJavaIcon(); |
12047 | 59 |
} |
60 |
}); |
|
61 |
} |
|
62 |
||
63 |
public static IconUIResource getCautionImageIcon() { |
|
64 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
65 |
return getAppIconCompositedOn(AquaIcon.SystemIcon.getCautionIcon()); |
|
66 |
} |
|
67 |
||
68 |
public static IconUIResource getStopImageIcon() { |
|
69 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
70 |
return getAppIconCompositedOn(AquaIcon.SystemIcon.getStopIcon()); |
|
71 |
} |
|
72 |
||
73 |
public static IconUIResource getLockImageIcon() { |
|
74 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
75 |
if (JRSUIUtils.Images.shouldUseLegacySecurityUIPath()) { |
|
76 |
final Image lockIcon = AquaUtils.getCImageCreator().createImageFromFile("/System/Library/CoreServices/SecurityAgent.app/Contents/Resources/Security.icns", kAlertIconSize, kAlertIconSize); |
|
77 |
return getAppIconCompositedOn(lockIcon); |
|
78 |
} |
|
79 |
||
80 |
final Image lockIcon = Toolkit.getDefaultToolkit().getImage("NSImage://NSSecurity"); |
|
81 |
return getAppIconCompositedOn(lockIcon); |
|
82 |
} |
|
83 |
||
84 |
static Image getGenericJavaIcon() { |
|
85 |
return java.security.AccessController.doPrivileged(new PrivilegedAction<Image>() { |
|
86 |
public Image run() { |
|
87 |
return com.apple.eawt.Application.getApplication().getDockIconImage(); |
|
88 |
} |
|
89 |
}); |
|
90 |
} |
|
91 |
||
92 |
static String getPathToThisApplication() { |
|
93 |
return java.security.AccessController.doPrivileged(new PrivilegedAction<String>() { |
|
94 |
public String run() { |
|
95 |
return FileManager.getPathToApplicationBundle(); |
|
96 |
} |
|
97 |
}); |
|
98 |
} |
|
99 |
||
100 |
static IconUIResource getAppIconCompositedOn(final SystemIcon systemIcon) { |
|
101 |
systemIcon.setSize(kAlertIconSize, kAlertIconSize); |
|
102 |
return getAppIconCompositedOn(systemIcon.createImage()); |
|
103 |
} |
|
104 |
||
105 |
private static final int kAlertIconSize = 64; |
|
106 |
static IconUIResource getAppIconCompositedOn(final Image background) { |
|
23258 | 107 |
|
24532
24831bd48764
8040279: [macosx] Do not use the base image in the MultiResolutionBufferedImage
alexsch
parents:
23666
diff
changeset
|
108 |
if (background instanceof MultiResolutionCachedImage) { |
23666
a54bf43b5ba9
8035069: [macosx] Loading resolution variants by demand
alexsch
parents:
23649
diff
changeset
|
109 |
int width = background.getWidth(null); |
24532
24831bd48764
8040279: [macosx] Do not use the base image in the MultiResolutionBufferedImage
alexsch
parents:
23666
diff
changeset
|
110 |
Image mrIconImage = ((MultiResolutionCachedImage) background).map( |
23666
a54bf43b5ba9
8035069: [macosx] Loading resolution variants by demand
alexsch
parents:
23649
diff
changeset
|
111 |
rv -> getAppIconImageCompositedOn(rv, rv.getWidth(null) / width)); |
a54bf43b5ba9
8035069: [macosx] Loading resolution variants by demand
alexsch
parents:
23649
diff
changeset
|
112 |
return new IconUIResource(new ImageIcon(mrIconImage)); |
a54bf43b5ba9
8035069: [macosx] Loading resolution variants by demand
alexsch
parents:
23649
diff
changeset
|
113 |
} |
23258 | 114 |
|
23666
a54bf43b5ba9
8035069: [macosx] Loading resolution variants by demand
alexsch
parents:
23649
diff
changeset
|
115 |
BufferedImage iconImage = getAppIconImageCompositedOn(background, 1); |
23258 | 116 |
return new IconUIResource(new ImageIcon(iconImage)); |
117 |
} |
|
118 |
||
119 |
static BufferedImage getAppIconImageCompositedOn(final Image background, int scaleFactor) { |
|
12047 | 120 |
|
23258 | 121 |
final int scaledAlertIconSize = kAlertIconSize * scaleFactor; |
122 |
final int kAlertSubIconSize = (int) (scaledAlertIconSize * 0.5); |
|
123 |
final int kAlertSubIconInset = scaledAlertIconSize - kAlertSubIconSize; |
|
124 |
final Icon smallAppIconScaled = new AquaIcon.CachingScalingIcon( |
|
125 |
kAlertSubIconSize, kAlertSubIconSize) { |
|
126 |
Image createImage() { |
|
24533
7c429f6f88d2
7124250: [macosx] JOptionPane dialogs show wrong icons
pchelko
parents:
24532
diff
changeset
|
127 |
return getGenericJavaIcon(); |
23258 | 128 |
} |
129 |
}; |
|
12047 | 130 |
|
23258 | 131 |
final BufferedImage image = new BufferedImage(scaledAlertIconSize, |
27268
56ae490e62d2
8059943: [macosx] Aqua LaF should use BI.TYPE_INT_ARGB_PRE for a better performance
serb
parents:
25859
diff
changeset
|
132 |
scaledAlertIconSize, BufferedImage.TYPE_INT_ARGB_PRE); |
12047 | 133 |
final Graphics g = image.getGraphics(); |
23258 | 134 |
g.drawImage(background, 0, 0, |
135 |
scaledAlertIconSize, scaledAlertIconSize, null); |
|
12047 | 136 |
if (g instanceof Graphics2D) { |
137 |
// improves icon rendering quality in Quartz |
|
23258 | 138 |
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_RENDERING, |
139 |
RenderingHints.VALUE_RENDER_QUALITY); |
|
12047 | 140 |
} |
141 |
||
23258 | 142 |
smallAppIconScaled.paintIcon(null, g, |
143 |
kAlertSubIconInset, kAlertSubIconInset); |
|
12047 | 144 |
g.dispose(); |
145 |
||
23258 | 146 |
return image; |
12047 | 147 |
} |
148 |
||
149 |
public static IconUIResource getTreeFolderIcon() { |
|
150 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
151 |
return AquaIcon.SystemIcon.getFolderIconUIResource(); |
|
152 |
} |
|
153 |
||
154 |
public static IconUIResource getTreeOpenFolderIcon() { |
|
155 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
156 |
return AquaIcon.SystemIcon.getOpenFolderIconUIResource(); |
|
157 |
} |
|
158 |
||
159 |
public static IconUIResource getTreeDocumentIcon() { |
|
160 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
161 |
return AquaIcon.SystemIcon.getDocumentIconUIResource(); |
|
162 |
} |
|
163 |
||
164 |
public static UIResource getTreeExpandedIcon() { |
|
165 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
166 |
return AquaIcon.getIconFor(new JRSUIControlSpec() { |
|
167 |
public void initIconPainter(final AquaPainter<? extends JRSUIState> painter) { |
|
168 |
painter.state.set(Widget.DISCLOSURE_TRIANGLE); |
|
169 |
painter.state.set(State.ACTIVE); |
|
170 |
painter.state.set(Direction.DOWN); |
|
171 |
painter.state.set(AlignmentHorizontal.CENTER); |
|
172 |
painter.state.set(AlignmentVertical.CENTER); |
|
173 |
} |
|
174 |
}, 20, 20); |
|
175 |
} |
|
176 |
||
177 |
public static UIResource getTreeCollapsedIcon() { |
|
178 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
179 |
return AquaIcon.getIconFor(new JRSUIControlSpec() { |
|
180 |
public void initIconPainter(final AquaPainter<? extends JRSUIState> painter) { |
|
181 |
painter.state.set(Widget.DISCLOSURE_TRIANGLE); |
|
182 |
painter.state.set(State.ACTIVE); |
|
183 |
painter.state.set(Direction.RIGHT); |
|
184 |
painter.state.set(AlignmentHorizontal.CENTER); |
|
185 |
painter.state.set(AlignmentVertical.CENTER); |
|
186 |
} |
|
187 |
}, 20, 20); |
|
188 |
} |
|
189 |
||
190 |
public static UIResource getTreeRightToLeftCollapsedIcon() { |
|
191 |
// public, because UIDefaults.ProxyLazyValue uses reflection to get this value |
|
192 |
return AquaIcon.getIconFor(new JRSUIControlSpec() { |
|
193 |
public void initIconPainter(final AquaPainter<? extends JRSUIState> painter) { |
|
194 |
painter.state.set(Widget.DISCLOSURE_TRIANGLE); |
|
195 |
painter.state.set(State.ACTIVE); |
|
196 |
painter.state.set(Direction.LEFT); |
|
197 |
painter.state.set(AlignmentHorizontal.CENTER); |
|
198 |
painter.state.set(AlignmentVertical.CENTER); |
|
199 |
} |
|
200 |
}, 20, 20); |
|
201 |
} |
|
202 |
||
203 |
static class NamedImageSingleton extends RecyclableSingleton<Image> { |
|
204 |
final String namedImage; |
|
205 |
||
206 |
NamedImageSingleton(final String namedImage) { |
|
207 |
this.namedImage = namedImage; |
|
208 |
} |
|
209 |
||
210 |
@Override |
|
211 |
protected Image getInstance() { |
|
23318
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
212 |
return getNSIcon(namedImage); |
12047 | 213 |
} |
214 |
} |
|
215 |
||
216 |
static class IconUIResourceSingleton extends RecyclableSingleton<IconUIResource> { |
|
217 |
final NamedImageSingleton holder; |
|
218 |
||
219 |
public IconUIResourceSingleton(final NamedImageSingleton holder) { |
|
220 |
this.holder = holder; |
|
221 |
} |
|
222 |
||
223 |
@Override |
|
224 |
protected IconUIResource getInstance() { |
|
225 |
return new IconUIResource(new ImageIcon(holder.get())); |
|
226 |
} |
|
227 |
} |
|
228 |
||
23649
f4f882f0056b
8035692: Fix serial lint warnings in mac-specific code
darcy
parents:
23328
diff
changeset
|
229 |
@SuppressWarnings("serial") // Superclass is not serializable across versions |
12047 | 230 |
static class InvertableImageIcon extends ImageIcon implements InvertableIcon, UIResource { |
231 |
Icon invertedImage; |
|
232 |
public InvertableImageIcon(final Image image) { |
|
233 |
super(image); |
|
234 |
} |
|
235 |
||
236 |
@Override |
|
237 |
public Icon getInvertedIcon() { |
|
238 |
if (invertedImage != null) return invertedImage; |
|
239 |
return invertedImage = new IconUIResource(new ImageIcon(AquaUtils.generateLightenedImage(getImage(), 100))); |
|
240 |
} |
|
241 |
} |
|
242 |
||
243 |
protected static final NamedImageSingleton northArrow = new NamedImageSingleton("NSMenuScrollUp"); |
|
244 |
protected static final IconUIResourceSingleton northArrowIcon = new IconUIResourceSingleton(northArrow); |
|
245 |
protected static final NamedImageSingleton southArrow = new NamedImageSingleton("NSMenuScrollDown"); |
|
246 |
protected static final IconUIResourceSingleton southArrowIcon = new IconUIResourceSingleton(southArrow); |
|
247 |
protected static final NamedImageSingleton westArrow = new NamedImageSingleton("NSMenuSubmenuLeft"); |
|
248 |
protected static final IconUIResourceSingleton westArrowIcon = new IconUIResourceSingleton(westArrow); |
|
249 |
protected static final NamedImageSingleton eastArrow = new NamedImageSingleton("NSMenuSubmenu"); |
|
250 |
protected static final IconUIResourceSingleton eastArrowIcon = new IconUIResourceSingleton(eastArrow); |
|
251 |
||
252 |
static Image getArrowImageForDirection(final int direction) { |
|
253 |
switch(direction) { |
|
254 |
case SwingConstants.NORTH: return northArrow.get(); |
|
255 |
case SwingConstants.SOUTH: return southArrow.get(); |
|
256 |
case SwingConstants.EAST: return eastArrow.get(); |
|
257 |
case SwingConstants.WEST: return westArrow.get(); |
|
258 |
} |
|
259 |
return null; |
|
260 |
} |
|
261 |
||
262 |
static Icon getArrowIconForDirection(int direction) { |
|
263 |
switch(direction) { |
|
264 |
case SwingConstants.NORTH: return northArrowIcon.get(); |
|
265 |
case SwingConstants.SOUTH: return southArrowIcon.get(); |
|
266 |
case SwingConstants.EAST: return eastArrowIcon.get(); |
|
267 |
case SwingConstants.WEST: return westArrowIcon.get(); |
|
268 |
} |
|
269 |
return null; |
|
270 |
} |
|
271 |
||
272 |
public static Icon getMenuArrowIcon() { |
|
273 |
return new InvertableImageIcon(AquaUtils.generateLightenedImage(eastArrow.get(), 25)); |
|
274 |
} |
|
275 |
||
276 |
public static Icon getMenuItemCheckIcon() { |
|
23318
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
277 |
return new InvertableImageIcon(AquaUtils.generateLightenedImage( |
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
278 |
getNSIcon("NSMenuItemSelection"), 25)); |
12047 | 279 |
} |
280 |
||
281 |
public static Icon getMenuItemDashIcon() { |
|
23318
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
282 |
return new InvertableImageIcon(AquaUtils.generateLightenedImage( |
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
283 |
getNSIcon("NSMenuMixedState"), 25)); |
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
284 |
} |
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
285 |
|
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
286 |
private static Image getNSIcon(String imageName) { |
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
287 |
Image icon = Toolkit.getDefaultToolkit() |
7da69afd4ffe
8031573: [macosx] Checkmarks of JCheckBoxMenuItems aren't rendered in high resolution on Retina
alexsch
parents:
23258
diff
changeset
|
288 |
.getImage("NSImage://" + imageName); |
24532
24831bd48764
8040279: [macosx] Do not use the base image in the MultiResolutionBufferedImage
alexsch
parents:
23666
diff
changeset
|
289 |
return icon; |
12047 | 290 |
} |
291 |
||
292 |
public static class NineSliceMetrics { |
|
293 |
public final int wCut, eCut, nCut, sCut; |
|
294 |
public final int minW, minH; |
|
295 |
public final boolean showMiddle, stretchH, stretchV; |
|
296 |
||
297 |
public NineSliceMetrics(final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut) { |
|
298 |
this(minWidth, minHeight, westCut, eastCut, northCut, southCut, true); |
|
299 |
} |
|
300 |
||
301 |
public NineSliceMetrics(final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean showMiddle) { |
|
302 |
this(minWidth, minHeight, westCut, eastCut, northCut, southCut, showMiddle, true, true); |
|
303 |
} |
|
304 |
||
305 |
public NineSliceMetrics(final int minWidth, final int minHeight, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean showMiddle, final boolean stretchHorizontally, final boolean stretchVertically) { |
|
306 |
this.wCut = westCut; this.eCut = eastCut; this.nCut = northCut; this.sCut = southCut; |
|
307 |
this.minW = minWidth; this.minH = minHeight; |
|
308 |
this.showMiddle = showMiddle; this.stretchH = stretchHorizontally; this.stretchV = stretchVertically; |
|
309 |
} |
|
310 |
} |
|
311 |
||
312 |
/* |
|
313 |
* A "paintable" which holds nine images, which represent a sliced up initial |
|
314 |
* image that can be streched from its middles. |
|
315 |
*/ |
|
316 |
public static class SlicedImageControl { |
|
317 |
final BufferedImage NW, N, NE; |
|
318 |
final BufferedImage W, C, E; |
|
319 |
final BufferedImage SW, S, SE; |
|
320 |
||
321 |
final NineSliceMetrics metrics; |
|
322 |
||
323 |
final int totalWidth, totalHeight; |
|
324 |
final int centerColWidth, centerRowHeight; |
|
325 |
||
326 |
public SlicedImageControl(final Image img, final int westCut, final int eastCut, final int northCut, final int southCut) { |
|
327 |
this(img, westCut, eastCut, northCut, southCut, true); |
|
328 |
} |
|
329 |
||
330 |
public SlicedImageControl(final Image img, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle) { |
|
331 |
this(img, westCut, eastCut, northCut, southCut, useMiddle, true, true); |
|
332 |
} |
|
333 |
||
334 |
public SlicedImageControl(final Image img, final int westCut, final int eastCut, final int northCut, final int southCut, final boolean useMiddle, final boolean stretchHorizontally, final boolean stretchVertically) { |
|
335 |
this(img, new NineSliceMetrics(img.getWidth(null), img.getHeight(null), westCut, eastCut, northCut, southCut, useMiddle, stretchHorizontally, stretchVertically)); |
|
336 |
} |
|
337 |
||
338 |
public SlicedImageControl(final Image img, final NineSliceMetrics metrics) { |
|
339 |
this.metrics = metrics; |
|
340 |
||
341 |
if (img.getWidth(null) != metrics.minW || img.getHeight(null) != metrics.minH) { |
|
342 |
throw new IllegalArgumentException("SlicedImageControl: template image and NineSliceMetrics don't agree on minimum dimensions"); |
|
343 |
} |
|
344 |
||
345 |
totalWidth = metrics.minW; |
|
346 |
totalHeight = metrics.minH; |
|
347 |
centerColWidth = totalWidth - metrics.wCut - metrics.eCut; |
|
348 |
centerRowHeight = totalHeight - metrics.nCut - metrics.sCut; |
|
349 |
||
350 |
NW = createSlice(img, 0, 0, metrics.wCut, metrics.nCut); |
|
351 |
N = createSlice(img, metrics.wCut, 0, centerColWidth, metrics.nCut); |
|
352 |
NE = createSlice(img, totalWidth - metrics.eCut, 0, metrics.eCut, metrics.nCut); |
|
353 |
W = createSlice(img, 0, metrics.nCut, metrics.wCut, centerRowHeight); |
|
354 |
C = metrics.showMiddle ? createSlice(img, metrics.wCut, metrics.nCut, centerColWidth, centerRowHeight) : null; |
|
355 |
E = createSlice(img, totalWidth - metrics.eCut, metrics.nCut, metrics.eCut, centerRowHeight); |
|
356 |
SW = createSlice(img, 0, totalHeight - metrics.sCut, metrics.wCut, metrics.sCut); |
|
357 |
S = createSlice(img, metrics.wCut, totalHeight - metrics.sCut, centerColWidth, metrics.sCut); |
|
358 |
SE = createSlice(img, totalWidth - metrics.eCut, totalHeight - metrics.sCut, metrics.eCut, metrics.sCut); |
|
359 |
} |
|
360 |
||
361 |
static BufferedImage createSlice(final Image img, final int x, final int y, final int w, final int h) { |
|
362 |
if (w == 0 || h == 0) return null; |
|
363 |
||
364 |
final BufferedImage slice = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB_PRE); |
|
365 |
final Graphics2D g2d = slice.createGraphics(); |
|
366 |
g2d.drawImage(img, 0, 0, w, h, x, y, x + w, y + h, null); |
|
367 |
g2d.dispose(); |
|
368 |
||
369 |
return slice; |
|
370 |
} |
|
371 |
||
372 |
public void paint(final Graphics g, final int x, final int y, final int w, final int h) { |
|
373 |
g.translate(x, y); |
|
374 |
||
375 |
if (w < totalWidth || h < totalHeight) { |
|
376 |
paintCompressed(g, w, h); |
|
377 |
} else { |
|
378 |
paintStretchedMiddles(g, w, h); |
|
379 |
} |
|
380 |
||
381 |
g.translate(-x, -y); |
|
382 |
} |
|
383 |
||
384 |
void paintStretchedMiddles(final Graphics g, final int w, final int h) { |
|
385 |
int baseX = metrics.stretchH ? 0 : ((w / 2) - (totalWidth / 2)); |
|
386 |
int baseY = metrics.stretchV ? 0 : ((h / 2) - (totalHeight / 2)); |
|
387 |
int adjustedWidth = metrics.stretchH ? w : totalWidth; |
|
388 |
int adjustedHeight = metrics.stretchV ? h : totalHeight; |
|
389 |
||
390 |
if (NW != null) g.drawImage(NW, baseX, baseY, null); |
|
391 |
if (N != null) g.drawImage(N, baseX + metrics.wCut, baseY, adjustedWidth - metrics.eCut - metrics.wCut, metrics.nCut, null); |
|
392 |
if (NE != null) g.drawImage(NE, baseX + adjustedWidth - metrics.eCut, baseY, null); |
|
393 |
if (W != null) g.drawImage(W, baseX, baseY + metrics.nCut, metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut, null); |
|
394 |
if (C != null) g.drawImage(C, baseX + metrics.wCut, baseY + metrics.nCut, adjustedWidth - metrics.eCut - metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut, null); |
|
395 |
if (E != null) g.drawImage(E, baseX + adjustedWidth - metrics.eCut, baseY + metrics.nCut, metrics.eCut, adjustedHeight - metrics.nCut - metrics.sCut, null); |
|
396 |
if (SW != null) g.drawImage(SW, baseX, baseY + adjustedHeight - metrics.sCut, null); |
|
397 |
if (S != null) g.drawImage(S, baseX + metrics.wCut, baseY + adjustedHeight - metrics.sCut, adjustedWidth - metrics.eCut - metrics.wCut, metrics.sCut, null); |
|
398 |
if (SE != null) g.drawImage(SE, baseX + adjustedWidth - metrics.eCut, baseY + adjustedHeight - metrics.sCut, null); |
|
399 |
||
400 |
/* |
|
401 |
if (NW != null) {g.setColor(Color.GREEN); g.fillRect(baseX, baseY, NW.getWidth(), NW.getHeight());} |
|
402 |
if (N != null) {g.setColor(Color.RED); g.fillRect(baseX + metrics.wCut, baseY, adjustedWidth - metrics.eCut - metrics.wCut, metrics.nCut);} |
|
403 |
if (NE != null) {g.setColor(Color.BLUE); g.fillRect(baseX + adjustedWidth - metrics.eCut, baseY, NE.getWidth(), NE.getHeight());} |
|
404 |
if (W != null) {g.setColor(Color.PINK); g.fillRect(baseX, baseY + metrics.nCut, metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut);} |
|
405 |
if (C != null) {g.setColor(Color.ORANGE); g.fillRect(baseX + metrics.wCut, baseY + metrics.nCut, adjustedWidth - metrics.eCut - metrics.wCut, adjustedHeight - metrics.nCut - metrics.sCut);} |
|
406 |
if (E != null) {g.setColor(Color.CYAN); g.fillRect(baseX + adjustedWidth - metrics.eCut, baseY + metrics.nCut, metrics.eCut, adjustedHeight - metrics.nCut - metrics.sCut);} |
|
407 |
if (SW != null) {g.setColor(Color.MAGENTA); g.fillRect(baseX, baseY + adjustedHeight - metrics.sCut, SW.getWidth(), SW.getHeight());} |
|
408 |
if (S != null) {g.setColor(Color.DARK_GRAY); g.fillRect(baseX + metrics.wCut, baseY + adjustedHeight - metrics.sCut, adjustedWidth - metrics.eCut - metrics.wCut, metrics.sCut);} |
|
409 |
if (SE != null) {g.setColor(Color.YELLOW); g.fillRect(baseX + adjustedWidth - metrics.eCut, baseY + adjustedHeight - metrics.sCut, SE.getWidth(), SE.getHeight());} |
|
410 |
*/ |
|
411 |
} |
|
412 |
||
413 |
void paintCompressed(final Graphics g, final int w, final int h) { |
|
414 |
final double heightRatio = h > totalHeight ? 1.0 : (double)h / (double)totalHeight; |
|
415 |
final double widthRatio = w > totalWidth ? 1.0 : (double)w / (double)totalWidth; |
|
416 |
||
417 |
final int northHeight = (int)(metrics.nCut * heightRatio); |
|
418 |
final int southHeight = (int)(metrics.sCut * heightRatio); |
|
419 |
final int centerHeight = h - northHeight - southHeight; |
|
420 |
||
421 |
final int westWidth = (int)(metrics.wCut * widthRatio); |
|
422 |
final int eastWidth = (int)(metrics.eCut * widthRatio); |
|
423 |
final int centerWidth = w - westWidth - eastWidth; |
|
424 |
||
425 |
if (NW != null) g.drawImage(NW, 0, 0, westWidth, northHeight, null); |
|
426 |
if (N != null) g.drawImage(N, westWidth, 0, centerWidth, northHeight, null); |
|
427 |
if (NE != null) g.drawImage(NE, w - eastWidth, 0, eastWidth, northHeight, null); |
|
428 |
if (W != null) g.drawImage(W, 0, northHeight, westWidth, centerHeight, null); |
|
429 |
if (C != null) g.drawImage(C, westWidth, northHeight, centerWidth, centerHeight, null); |
|
430 |
if (E != null) g.drawImage(E, w - eastWidth, northHeight, eastWidth, centerHeight, null); |
|
431 |
if (SW != null) g.drawImage(SW, 0, h - southHeight, westWidth, southHeight, null); |
|
432 |
if (S != null) g.drawImage(S, westWidth, h - southHeight, centerWidth, southHeight, null); |
|
433 |
if (SE != null) g.drawImage(SE, w - eastWidth, h - southHeight, eastWidth, southHeight, null); |
|
434 |
} |
|
435 |
} |
|
436 |
||
437 |
public abstract static class RecyclableSlicedImageControl extends RecyclableObject<SlicedImageControl> { |
|
438 |
final NineSliceMetrics metrics; |
|
439 |
||
440 |
public RecyclableSlicedImageControl(final NineSliceMetrics metrics) { |
|
441 |
this.metrics = metrics; |
|
442 |
} |
|
443 |
||
444 |
@Override |
|
445 |
protected SlicedImageControl create() { |
|
446 |
return new SlicedImageControl(createTemplateImage(metrics.minW, metrics.minH), metrics); |
|
447 |
} |
|
448 |
||
449 |
protected abstract Image createTemplateImage(final int width, final int height); |
|
450 |
} |
|
451 |
||
452 |
// when we use SystemColors, we need to proxy the color with something that implements UIResource, |
|
453 |
// so that it will be uninstalled when the look and feel is changed. |
|
23649
f4f882f0056b
8035692: Fix serial lint warnings in mac-specific code
darcy
parents:
23328
diff
changeset
|
454 |
@SuppressWarnings("serial") // JDK implementation class |
12047 | 455 |
private static class SystemColorProxy extends Color implements UIResource { |
456 |
final Color color; |
|
457 |
public SystemColorProxy(final Color color) { |
|
458 |
super(color.getRGB()); |
|
459 |
this.color = color; |
|
460 |
} |
|
461 |
||
462 |
public int getRGB() { |
|
463 |
return color.getRGB(); |
|
464 |
} |
|
465 |
} |
|
466 |
||
467 |
public static Color getWindowBackgroundColorUIResource() { |
|
468 |
//return AquaNativeResources.getWindowBackgroundColorUIResource(); |
|
469 |
return new SystemColorProxy(SystemColor.window); |
|
470 |
} |
|
471 |
||
472 |
public static Color getTextSelectionBackgroundColorUIResource() { |
|
473 |
return new SystemColorProxy(SystemColor.textHighlight); |
|
474 |
} |
|
475 |
||
476 |
public static Color getTextSelectionForegroundColorUIResource() { |
|
477 |
return new SystemColorProxy(SystemColor.textHighlightText); |
|
478 |
} |
|
479 |
||
480 |
public static Color getSelectionBackgroundColorUIResource() { |
|
481 |
return new SystemColorProxy(SystemColor.controlHighlight); |
|
482 |
} |
|
483 |
||
484 |
public static Color getSelectionForegroundColorUIResource() { |
|
485 |
return new SystemColorProxy(SystemColor.controlLtHighlight); |
|
486 |
} |
|
487 |
||
488 |
public static Color getFocusRingColorUIResource() { |
|
489 |
return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.KEYBOARD_FOCUS_COLOR)); |
|
490 |
} |
|
491 |
||
492 |
public static Color getSelectionInactiveBackgroundColorUIResource() { |
|
493 |
return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_BACKGROUND_COLOR)); |
|
494 |
} |
|
495 |
||
496 |
public static Color getSelectionInactiveForegroundColorUIResource() { |
|
497 |
return new SystemColorProxy(LWCToolkit.getAppleColor(LWCToolkit.INACTIVE_SELECTION_FOREGROUND_COLOR)); |
|
498 |
} |
|
24533
7c429f6f88d2
7124250: [macosx] JOptionPane dialogs show wrong icons
pchelko
parents:
24532
diff
changeset
|
499 |
} |