Irving_wei 发表于 2013-1-17 23:33:29

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]
查看完整版本: SWT 显示动态图片gif