纯属抄袭 -- SWT如何实现不规则窗口
网上的强人实在是多,今天我也抄袭一下吧。我一般是比较鄙视的,在网上一查,相同的文章一大片,实在不明白为啥大家这么喜欢抄别人的,不过我今天也抄一把,但是我希望能够写一些自己的理解和总结。
事实上,这里的秘密在于图形的选择,而不在于其他,当然了,实现不规则窗体的方法不只一种,只是在我抄袭的这种方法里,是通过“抠出”PNG图片中的透明层来实现的,所以你想实现的那个宝贝界面应该是一个透明的PNG图片。我对图片类型没有深入的研究,不知道JPG、BMP等等图片是不是也有什么透明层,所以我只能照葫芦画瓢,使用PNG格式的图片;
那么一旦图片选定了,怎么才能“抠出”那些我们不需要的区域呢?道理很简单但很蠢,那就是两层循环分别沿x、y两个坐标,从图片的左上到右下找出每一个像素的ImageData,看看这个像素是不是“透明”的,这里还要说明一点,所谓透明是指图片上的像素颜色和桌面底色是不是相同,因此你可以自己根据自己应用的需要设置自己认为的透明基色。然后把所有这些像素保存到一个Region中,这样我们的shell就可以在显示的时候将这个Region“抠出去”;这样一个不规则窗口就创建出来了;
可是这里的一个问题是:图片千万不要太大,就算是现在的计算机速度快吧,也不能这么折腾,那毕竟是两层循环一个一个像素的查呀,程序可不是全部都在UI上,没必要为了显示个界面搞半天吧,所以尽量选择小图片。想想emule的那个驴子如果搞得桌面那么大,估计用JAVA实现也够呛。
下面就是我的抄袭:
2
3 import java.io.IOException;
4 import java.io.InputStream;
5
6 import org.eclipse.swt.SWT;
7 import org.eclipse.swt.graphics.Image;
8 import org.eclipse.swt.graphics.ImageData;
9 import org.eclipse.swt.graphics.Point;
10 import org.eclipse.swt.graphics.Region;
11 import org.eclipse.swt.widgets.Display;
12 import org.eclipse.swt.widgets.Event;
13 import org.eclipse.swt.widgets.Listener;
14 import org.eclipse.swt.widgets.Shell;
15
16 public class ShapeWindow {
17
18 public static void main(String [] args){
19 ShapeWindow window = new ShapeWindow();
20 window.open();
21 }
22
23 private Display display;
24 private Image image;
25 private Shell shell;
26 private ImageData id;
27 private Region region;
28
29 private void open() {
30 // TODO Auto-generated method stub
31 createContents();
32 shell.open();
33 shell.layout();
34 while(!shell.isDisposed()){
35 if (!display.readAndDispatch())
36 display.sleep();
37 }
38 }
39
40 private void createContents() {
41 // TODO Auto-generated method stub
42 display = Display.getDefault();
43 shell = new Shell(display, SWT.NO_TRIM);
44 shell.setText("形状窗口");
45
46 image = getImage();
47 region = new Region();
48 if (id.alphaData != null) {
49 for (int y = 0; y < id.height; y++) {
50 for (int x = 0; x < id.width; x++) {
51 if (id.getAlpha(x, y) == 255) {
52 region.add( x, y, 1, 1);
53 }
54 }
55 }
56 } else {
57 ImageData mask = id.getTransparencyMask();
58 for (int y = 0; y < mask.height; y++) {
59 for (int x = 0; x < mask.width; x++) {
60 if (mask.getPixel(x, y) != 0 ) {
61 region.add( x, y, 1, 1);
62 }
63 }
64 }
65 }
66 shell.setRegion(region);
67 shell.setSize(id.width, id.height);
68 Listener listen = new Listener() {
69 int startX, startY;
70
71 public void handleEvent(Event e) {
72 if (e.type == SWT.KeyDown && e.character == SWT.ESC) {
73 shell.dispose();
74 }
75 if (e.type == SWT.MouseDown && e.button == 1) {
76 startX = e.x;
77 startY = e.y;
78 }
79 if (e.type == SWT.MouseMove && (e.stateMask & SWT.BUTTON1) != 0) {
80 Point p = shell.toDisplay(e.x, e.y);
81 p.x -= startX;
82 p.y -= startY;
83 shell.setLocation(p);
84 }
85 if (e.type == SWT.Paint) {
86 e.gc.drawImage(image, id.x, id.y);
87 }
88 }
89 };
90 shell.addListener(SWT.KeyDown, listen);
91 shell.addListener(SWT.MouseDown, listen);
92 shell.addListener(SWT.MouseMove, listen);
93 shell.addListener(SWT.Paint, listen);
94 }
95
96 private Image getImage() {
97 // TODO Auto-generated method stub
98 Image image = null;
99 InputStream is = ShapeWindow.class.getResourceAsStream("shape.png");
100 id = new ImageData(is);
101 if(id != null){
102 image = new Image(display,id);
103 }
104 try {
105 is.close();
106 } catch (IOException e) {
107 // TODO Auto-generated catch block
108 e.printStackTrace();
109 }
110 return image;
111 }
112 }
113
posted on 2010-08-12 15:30 wayne.wang 阅读(1396) 评论(4) 编辑 收藏 举报