在做AutomatonDesigner的时候,使用了SWT的绘图技术,其中要把用户通过组建构建好的自动机模型保存成jpg等图片的形式,主要使用如下的代码。
需要说明的是,这段代码的基本原理是通过操作系统,向控件control发送重绘消息,让其在新构建的GC中进行重绘,因此控件需要支持WM_PRINT消息,并且暂时此函数只支持Win32系统,使用之前可以用OS.IsWin32s所获得的boolean值判断当前系统是否是Win32系统。


1
private
static
final
int
WM_PRINT
=
0x0317
;
2 private static final int PRF_NONCLIENT = 0x00000002 ;
3 private static final int PRF_CLIENT = 0x00000004 ;
4 private static final int PRF_ERASEBKGND = 0x00000008 ;
5
6 public static Image makeShotImage(Control control) {
7 int width = control.getBounds().width;
8 int height = control.getBounds().height;
9 if (width > 0 && height > 0 ) {
10 Image image = new Image(control.getDisplay(), width, height);
11 GC gc = new GC(image);
12 OS.SendMessage(control.handle, WM_PRINT, gc.handle, PRF_CLIENT
13 | PRF_ERASEBKGND | PRF_NONCLIENT);
14 gc.dispose();
15 return image;
16 }
17 return null ;
18 }
2 private static final int PRF_NONCLIENT = 0x00000002 ;
3 private static final int PRF_CLIENT = 0x00000004 ;
4 private static final int PRF_ERASEBKGND = 0x00000008 ;
5
6 public static Image makeShotImage(Control control) {
7 int width = control.getBounds().width;
8 int height = control.getBounds().height;
9 if (width > 0 && height > 0 ) {
10 Image image = new Image(control.getDisplay(), width, height);
11 GC gc = new GC(image);
12 OS.SendMessage(control.handle, WM_PRINT, gc.handle, PRF_CLIENT
13 | PRF_ERASEBKGND | PRF_NONCLIENT);
14 gc.dispose();
15 return image;
16 }
17 return null ;
18 }
然后,在做Image保存的时候,可以使用ImageLoader类来进行保存操作,当然它还有Load方法,可以参见SWT的API文档。
注意在本部分loader.data是一个ImageData的数组,如果在不进行new操作而直接对其下标为0的部分进行赋值的话会有NullPointException的异常。


1
public
void
doSaveAs() {
2 FileDialog dlg = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE);
3 dlg.setFileName( this .getTitle() + " .jpg " );
4 dlg.setFilterNames( new String[]{ " Image Files " });
5 dlg.setFilterExtensions( new String[]{ " *.jpg " });
6 String fileName = dlg.open();
7 if (fileName == null ){
8 return ;
9 }
10 File file = new File(fileName);
11 if (file.exists()){
12 if ( ! MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), " 已存在 " , " 该文件已经存在,是否覆盖? " ))
13 return ;
14 }
15 ImageLoader loader = new ImageLoader();
16 loader.data = new ImageData []{CommonTool.makeShotImage(canvas).getImageData()};
17 loader.save(fileName, SWT.IMAGE_JPEG);
18 setDirty( false );
19 firePropertyChange(PROP_DIRTY);
20 }
2 FileDialog dlg = new FileDialog(Display.getCurrent().getActiveShell(), SWT.SAVE);
3 dlg.setFileName( this .getTitle() + " .jpg " );
4 dlg.setFilterNames( new String[]{ " Image Files " });
5 dlg.setFilterExtensions( new String[]{ " *.jpg " });
6 String fileName = dlg.open();
7 if (fileName == null ){
8 return ;
9 }
10 File file = new File(fileName);
11 if (file.exists()){
12 if ( ! MessageDialog.openQuestion(Display.getCurrent().getActiveShell(), " 已存在 " , " 该文件已经存在,是否覆盖? " ))
13 return ;
14 }
15 ImageLoader loader = new ImageLoader();
16 loader.data = new ImageData []{CommonTool.makeShotImage(canvas).getImageData()};
17 loader.save(fileName, SWT.IMAGE_JPEG);
18 setDirty( false );
19 firePropertyChange(PROP_DIRTY);
20 }