Glossy 效果,顧名思義,就是玻璃質(zhì)的光澤透明的效果,在Windows平臺下的應(yīng)用越來越廣泛,從Media Player10開始,它的button已經(jīng)運用上了此效果?,F(xiàn)在但凡是微軟新發(fā)布的軟件,十有八九都帶有g(shù)lossy特效。Glossy 效果使用了Gdi Plus的API,因此在Win98和Win2000下,必須安裝gdiplus.dll才能使用,此動態(tài)鏈接庫不大,只有700多K,但是想要在自己的應(yīng)用程序中畫出絢麗多彩的效果,那是少不了這個小東西的。關(guān)于Glossy效果的描述,可以參見CodeProject上的一片文章
WindowsVistaRenderer,http://www.codeproject.com/KB/vista/WindowsVistaRenderer.aspx
Glossy特效有一個重要的組成部分,就是橢圓的光暈,此效果在Linux下可能并沒有實現(xiàn)(并未下定論,我還沒有深入研究過Linux下的圖形庫),
所以SWT的Gdip并沒有將其公開出來,而是放入custom的API里,也就是說,你可以自行調(diào)用此效果的API,但是SWT并不負責為你提供封裝,
因此你并不能使用GC來實現(xiàn)該特效,這對我們的界面開發(fā)極為不利,自己調(diào)用Gdip的API,繁瑣不說,還很容易導致JVM退出。
為了能夠方便的使用GC來畫出此特效,我們不得不采用一些非常規(guī)的手段:反射。利用反射我們可以拿到GC的一些內(nèi)部數(shù)據(jù),在這個地方,我們只需要拿到GCData就可以,它包含了畫圖所需要具備的元素。Glossy效果需要使用PathGradientBrush,我們把這個刷子賦給GCData,就可以使用GC來畫出glossy特效了。
1 public class GCExtension {
2
3 private GC gc;
4
5 private GCData data;
6
7 public GCExtension(GC gc) {
8 this.gc = gc;
9 data = getGCData(gc);
10 }
11
12 public void fillGradientPath(Path path, float[] centerPoint,
13 Color centerColor, int centerColorAlpha, Color[] surroundColors,
14 int[] surroundColorAlphas) {
15 if (gc == null || gc.handle == 0)
16 SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
17 if (path == null || centerPoint == null || centerColor == null
18 || surroundColorAlphas == null)
19 SWT.error(SWT.ERROR_NULL_ARGUMENT);
20 if (path.handle == 0 || centerPoint.length < 2
21 || centerColor.handle == 0
22 || surroundColors.length != surroundColorAlphas.length)
23 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
24 for (int i = 0; i < surroundColors.length; i++) {
25 if (surroundColors[i] == null || surroundColors[i].handle == 0)
26 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
27 }
28
29 int brush = Gdip.PathGradientBrush_new(path.handle);
30 if (brush == 0)
31 SWT.error(SWT.ERROR_NO_HANDLES);
32 PointF point = new PointF();
33 point.X = centerPoint[0];
34 point.Y = centerPoint[1];
35 Gdip.PathGradientBrush_SetCenterPoint(brush, point);
36
37 int colorRef = centerColor.handle;
38 int rgb = ((colorRef >> 16) & 0xFF) | (colorRef & 0xFF00)
39 | ((colorRef & 0xFF) << 16);
40 int color = Gdip.Color_new(centerColorAlpha << 24 | rgb);
41 if (color == 0)
42 SWT.error(SWT.ERROR_NO_HANDLES);
43 Gdip.PathGradientBrush_SetCenterColor(brush, color);
44 Gdip.Color_delete(color);
45
46 int[] colors = new int[surroundColors.length];
47 for (int i = 0; i < surroundColors.length; i++) {
48 colorRef = surroundColors[i].handle;
49 rgb = ((colorRef >> 16) & 0xFF) | (colorRef & 0xFF00)
50 | ((colorRef & 0xFF) << 16);
51 colors[i] = Gdip.Color_new(surroundColorAlphas[i] << 24 | rgb);
52 if (colors[i] == 0)
53 SWT.error(SWT.ERROR_NO_HANDLES);
54 }
55 Gdip.PathGradientBrush_SetSurroundColors(brush, colors,
56 new int[] { colors.length });
57 for (int i = 0; i < surroundColors.length; i++) {
58 Gdip.Color_delete(colors[i]);
59 }
60 data.gdipBrush = brush;
61 boolean advanced = gc.getAdvanced();
62 if (!advanced)
63 gc.setAdvanced(true);
64 int mode = Extension.GetPolyFillMode(gc.handle) == Extension.WINDING ? Gdip.FillModeWinding
65 : Gdip.FillModeAlternate;
66 Gdip.GraphicsPath_SetFillMode(path.handle, mode);
67 Gdip.Graphics_FillPath(data.gdipGraphics, data.gdipBrush, path.handle);
68 if (!advanced)
69 gc.setAdvanced(false);
70 if (data.gdipBrush != 0) {
71 Gdip.PathGradientBrush_delete(data.gdipBrush);
72 data.gdipBrush = 0;
73 }
74 }
75
76 private GCData getGCData(GC gc) {
77 GCData data = null;
78 try {
79 Object obj = null;
80 Field field = gc.getClass().getDeclaredField("data");
81 if (field != null) {
82 field.setAccessible(true);
83 obj = field.get(gc);
84 }
85 if (obj != null && obj instanceof GCData)
86 data = (GCData) obj;
87 } catch (Exception e) {
88
89 }
90 return data;
91 }
92 }
特效截圖: