SWT 显示动态图片gif
站在巨人的肩膀上:http://blog.csdn.net/xcl119xcl/archive/2010/01/22/5224444.aspx因为SWT的ImageLoader支持读写以上所有格式的图片,所以实现起来比较简单。主要解决了两个问题。第一个问题是播放GIF动画,通过 ImageLoader读入GIF的所有帧以及间隔时间,然后用Display.timerExec实现Timer播放。第二个问题是对图片的 Scrollbar支持以及pack支持。SWT.H_SCROLL和SWT.V_SCROLL 虽然加上了滚动条,但是不起作用,需要监听滚动条的SWT.Selection事件。另外,加上滚动条后,pack无法得到大小,不能正确的pack。需要重载computeSize。
/*** 负责显示各种格式的图片 **@author 喜来乐哈哈*/ public classImageViewerextendsCanvas { protectedPoint origin= newPoint( 0 ,0 ); protectedImage image; protectedImageData[] imageDatas; protectedImage[] images; protected intcurrent; private intrepeatCount; privateRunnable animationTimer; privateScrollBar hBar; privateScrollBar vBar; privateColor bg; privateDisplay display; publicImageViewer(Composite parent) { super (parent, SWT.NO_BACKGROUND|SWT.NO_REDRAW_RESIZE|SWT.V_SCROLL |SWT.H_SCROLL); hBar=getHorizontalBar(); vBar=getVerticalBar(); bg=getBackground(); display=getDisplay(); addListeners(); } public voidsetImage(ImageData imageData) { checkWidget(); stopAnimationTimer(); this .image= newImage(display, imageData); this .imageDatas= null ; this .images= null ; redraw(); } /** *@paramrepeatCount 0 forever */ public voidsetImages(ImageData[] imageDatas,intrepeatCount) { checkWidget(); this .image= null ; this .imageDatas=imageDatas; this .repeatCount=repeatCount; convertImageDatasToImages(); startAnimationTimer(); redraw(); } @Override publicPoint computeSize( intwHint,inthHint,booleanchanged) { checkWidget(); Image image=getCurrentImage(); if(image!= null ) { Rectangle rect=image.getBounds(); Rectangle trim=computeTrim( 0 ,0 , rect.width, rect.height); return newPoint(trim.width, trim.height); } return newPoint(wHint, hHint); } @Override public voiddispose() { if(image!= null ) image.dispose(); if(images!= null ) for( inti= 0 ; i<images.length; i ++ ) images.dispose(); super .dispose(); } protected voidpaint(Event e) { Image image=getCurrentImage(); if(image== null ) return ; GC gc=e.gc; gc.drawImage(image, origin.x, origin.y); gc.setBackground(bg); Rectangle rect=image.getBounds(); Rectangle client=getClientArea(); intmarginWidth=client.width-rect.width; if(marginWidth> 0 ) { gc.fillRectangle(rect.width,0 , marginWidth, client.height); } intmarginHeight=client.height-rect.height; if(marginHeight> 0 ) { gc.fillRectangle( 0 , rect.height, client.width, marginHeight); } } voidaddListeners() { hBar.addListener(SWT.Selection,newListener() { public voidhandleEvent(Event arg0) { hscroll(); } }); vBar.addListener(SWT.Selection,newListener() { public voidhandleEvent(Event arg0) { vscroll(); } }); addListener(SWT.Resize,newListener() { public voidhandleEvent(Event e) { resize(); } }); addListener(SWT.Paint,newListener() { public voidhandleEvent(Event e) { paint(e); } }); } voidhscroll() { Image image=getCurrentImage(); if(image!= null ) { inthSelection=hBar.getSelection(); intdestX= - hSelection-origin.x; Rectangle rect=image.getBounds(); scroll(destX,0 ,0 ,0 , rect.width, rect.height,false ); origin.x= - hSelection; } } voidvscroll() { Image image=getCurrentImage(); if(image!= null ) { intvSelection=vBar.getSelection(); intdestY= - vSelection-origin.y; Rectangle rect=image.getBounds(); scroll( 0 , destY,0 ,0 , rect.width, rect.height,false ); origin.y= - vSelection; } } voidresize() { Image image=getCurrentImage(); if(image== null ) return ; Rectangle rect=image.getBounds(); Rectangle client=getClientArea(); hBar.setMaximum(rect.width); vBar.setMaximum(rect.height); hBar.setThumb(Math.min(rect.width, client.width)); vBar.setThumb(Math.min(rect.height, client.height)); inthPage=rect.width-client.width; intvPage=rect.height-client.height; inthSelection=hBar.getSelection(); intvSelection=vBar.getSelection(); if(hSelection>=hPage) { if(hPage<= 0 ) hSelection= 0 ; origin.x= - hSelection; } if(vSelection>=vPage) { if(vPage<= 0 ) vSelection= 0 ; origin.y= - vSelection; } redraw(); } voidconvertImageDatasToImages() { images= newImage; //Step 1: Determine the size of the resulting images. intwidth=imageDatas[ 0 ].width; intheight=imageDatas[ 0 ].height; //Step 2: Construct each image. inttransition=SWT.DM_FILL_BACKGROUND; for( inti= 0 ; i<imageDatas.length; i ++ ) { ImageData id=imageDatas; images= newImage(display, width, height); GC gc= newGC(images); //Do the transition from the previous image. switch(transition) { caseSWT.DM_FILL_NONE: caseSWT.DM_UNSPECIFIED: //Start from last image. gc.drawImage(images,0 ,0 ); break ; caseSWT.DM_FILL_PREVIOUS: //Start from second last image. gc.drawImage(images,0 ,0 ); break ; default : //DM_FILL_BACKGROUND or anything else, //just fill with default background. gc.setBackground(bg); gc.fillRectangle( 0 ,0 , width, height); break ; } //Draw the current image and clean up. Image img= newImage(display, id); gc.drawImage(img,0 ,0 , id.width, id.height, id.x, id.y, id.width, id.height); img.dispose(); gc.dispose(); //Compute the next transition. //Special case: Can't do DM_FILL_PREVIOUS on the //second image since there is no "second last" //image to use. transition=id.disposalMethod; if(i== 0 &&transition==SWT.DM_FILL_PREVIOUS) transition=SWT.DM_FILL_NONE; } } Image getCurrentImage() { if(image!= null ) returnimage; if(images== null ) return null ; returnimages; } voidstartAnimationTimer() { if(images== null ||images.length< 2 ) return ; final intdelay=imageDatas.delayTime* 10 ; display.timerExec(delay, animationTimer= newRunnable() { public voidrun() { if(isDisposed()) return ; current=(current+ 1 )%images.length; redraw(); if(current+ 1 ==images.length&&repeatCount!= 0 && -- repeatCount<= 0 ) return ; display.timerExec(delay,this ); } }); } voidstopAnimationTimer() { if(animationTimer!= null ) display.timerExec( - 1 , animationTimer); }}
测试程序
public classImageCanvasTest { public static voidmain(String[] args) { Display display= newDisplay(); finalShell shell= newShell(display); ImageViewer ic= newImageViewer(shell); shell.setLayout( newFillLayout()); FileDialog dialog= newFileDialog(shell, SWT.OPEN); dialog.setText( " Open an image file or cancel " ); String string=dialog.open(); ImageLoader loader= newImageLoader(); ImageData[] imageDatas=loader.load(string); if(imageDatas.length== 0 ) return ; else if(imageDatas.length== 1 ) { ic.setImage(imageDatas[ 0 ]); }else{ ic.setImages(imageDatas, loader.repeatCount); } ic.pack(); shell.pack(); shell.open(); while( ! shell.isDisposed()) { if( ! display.readAndDispatch()) display.sleep(); } display.dispose(); }}
在对GIF图片的支持上,Swing要做的好很多,一句label.setIcon(new ImageIcon(name))就搞定GIF动画了。
页:
[1]