六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 72|回复: 0

SWT 显示动态图片gif

[复制链接]

升级  7.33%

13

主题

13

主题

13

主题

秀才

Rank: 2

积分
61
 楼主| 发表于 2013-1-17 23:33:29 | 显示全部楼层 |阅读模式
站在巨人的肩膀上: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   class  ImageViewer  extends  Canvas {     protected  Point origin  =   new  Point( 0 ,  0 );     protected  Image image;     protected  ImageData[] imageDatas;     protected  Image[] images;     protected   int  current;     private   int  repeatCount;     private  Runnable animationTimer;     private  ScrollBar hBar;     private  ScrollBar vBar;     private  Color bg;     private  Display display;     public  ImageViewer(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   void  setImage(ImageData imageData) {        checkWidget();        stopAnimationTimer();         this .image  =   new  Image(display, imageData);         this .imageDatas  =   null ;         this .images  =   null ;        redraw();    }     /**      *  @param  repeatCount 0 forever      */      public   void  setImages(ImageData[] imageDatas,  int  repeatCount) {        checkWidget();         this .image  =   null ;         this .imageDatas  =  imageDatas;         this .repeatCount  =  repeatCount;        convertImageDatasToImages();        startAnimationTimer();        redraw();    }    @Override     public  Point computeSize( int  wHint,  int  hHint,  boolean  changed) {        checkWidget();        Image image  =  getCurrentImage();         if  (image  !=   null ) {            Rectangle rect  =  image.getBounds();            Rectangle trim  =  computeTrim( 0 ,  0 , rect.width, rect.height);             return   new  Point(trim.width, trim.height);        }         return   new  Point(wHint, hHint);    }    @Override     public   void  dispose() {         if  (image  !=   null )            image.dispose();         if  (images  !=   null )             for  ( int  i  =   0 ; i  <  images.length; i ++ )                images.dispose();         super .dispose();    }     protected   void  paint(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();         int  marginWidth  =  client.width  -  rect.width;         if  (marginWidth  >   0 ) {            gc.fillRectangle(rect.width,  0 , marginWidth, client.height);        }         int  marginHeight  =  client.height  -  rect.height;         if  (marginHeight  >   0 ) {            gc.fillRectangle( 0 , rect.height, client.width, marginHeight);        }    }     void  addListeners() {        hBar.addListener(SWT.Selection,  new  Listener() {             public   void  handleEvent(Event arg0) {                hscroll();            }        });        vBar.addListener(SWT.Selection,  new  Listener() {             public   void  handleEvent(Event arg0) {                vscroll();            }        });        addListener(SWT.Resize,  new  Listener() {             public   void  handleEvent(Event e) {                resize();            }        });        addListener(SWT.Paint,  new  Listener() {             public   void  handleEvent(Event e) {                paint(e);            }        });    }     void  hscroll() {        Image image  =  getCurrentImage();         if  (image  !=   null ) {             int  hSelection  =  hBar.getSelection();             int  destX  =   - hSelection  -  origin.x;            Rectangle rect  =  image.getBounds();            scroll(destX,  0 ,  0 ,  0 , rect.width, rect.height,  false );            origin.x  =   - hSelection;        }    }     void  vscroll() {        Image image  =  getCurrentImage();         if  (image  !=   null ) {             int  vSelection  =  vBar.getSelection();             int  destY  =   - vSelection  -  origin.y;            Rectangle rect  =  image.getBounds();            scroll( 0 , destY,  0 ,  0 , rect.width, rect.height,  false );            origin.y  =   - vSelection;        }    }     void  resize() {        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));         int  hPage  =  rect.width  -  client.width;         int  vPage  =  rect.height  -  client.height;         int  hSelection  =  hBar.getSelection();         int  vSelection  =  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();    }     void  convertImageDatasToImages() {        images  =   new  Image[imageDatas.length];         //  Step 1: Determine the size of the resulting images.          int  width  =  imageDatas[ 0 ].width;         int  height  =  imageDatas[ 0 ].height;         //  Step 2: Construct each image.          int  transition  =  SWT.DM_FILL_BACKGROUND;         for  ( int  i  =   0 ; i  <  imageDatas.length; i ++ ) {            ImageData id  =  imageDatas;            images  =   new  Image(display, width, height);            GC gc  =   new  GC(images);             //  Do the transition from the previous image.              switch  (transition) {             case  SWT.DM_FILL_NONE:             case  SWT.DM_UNSPECIFIED:                 //  Start from last image.                 gc.drawImage(images[i  -   1 ],  0 ,  0 );                 break ;             case  SWT.DM_FILL_PREVIOUS:                 //  Start from second last image.                 gc.drawImage(images[i  -   2 ],  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  =   new  Image(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 )             return  image;         if  (images  ==   null )             return   null ;         return  images[current];    }     void  startAnimationTimer() {         if  (images  ==   null   ||  images.length  <   2 )             return ;         final   int  delay  =  imageDatas[current].delayTime  *   10 ;        display.timerExec(delay, animationTimer  =   new  Runnable() {             public   void  run() {                 if  (isDisposed())                     return ;                current  =  (current  +   1 )  %  images.length;                redraw();                 if  (current  +   1   ==  images.length  &&  repeatCount  !=   0                          &&   -- repeatCount  <=   0 )                     return ;                display.timerExec(delay,  this );            }        });    }     void  stopAnimationTimer() {         if  (animationTimer  !=   null )            display.timerExec( - 1 , animationTimer);    }}

测试程序

public   class  ImageCanvasTest {     public   static   void  main(String[] args) {        Display display  =   new  Display();         final  Shell shell  =   new  Shell(display);        ImageViewer ic  =   new  ImageViewer(shell);        shell.setLayout( new  FillLayout());        FileDialog dialog  =   new  FileDialog(shell, SWT.OPEN);        dialog.setText( " Open an image file or cancel " );        String string  =  dialog.open();        ImageLoader loader  =   new  ImageLoader();        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动画了。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表