SWT 显示动态图片gif

因为SWT的ImageLoader支持读写以上所有格式的图片,所以实现起来比较简单。主要解决了两个问题。第一个问题是播放GIF动画,通过 ImageLoader读入GIF的所有帧以及间隔时间,然后用Display.timerExec实现Timer播放。第二个问题是对图片的 Scrollbar支持以及pack支持。SWT.H_SCROLL和SWT.V_SCROLL 虽然加上了滚动条,但是不起作用,需要监听滚动条的SWT.Selection事件。另外,加上滚动条后,pack无法得到大小,不能正确的pack。需要重载computeSize。


Java代码 复制代码  收藏代码
  1. /**   
  2.  * 负责显示各种格式的图片  
  3.  *   
  4.  *  @author 喜来乐哈哈  
  5.   */    
  6. public   class  ImageViewer  extends  Canvas {   
  7.   
  8.      protected  Point origin  =   new  Point( 0 ,  0 );   
  9.      protected  Image image;   
  10.      protected  ImageData[] imageDatas;   
  11.      protected  Image[] images;   
  12.      protected   int  current;   
  13.   
  14.      private   int  repeatCount;   
  15.      private  Runnable animationTimer;   
  16.      private  ScrollBar hBar;   
  17.      private  ScrollBar vBar;   
  18.      private  Color bg;   
  19.      private  Display display;   
  20.   
  21.      public  ImageViewer(Composite parent) {   
  22.          super (parent, SWT.NO_BACKGROUND  |  SWT.NO_REDRAW_RESIZE  |  SWT.V_SCROLL   
  23.                  |  SWT.H_SCROLL);   
  24.   
  25.         hBar  =  getHorizontalBar();   
  26.         vBar  =  getVerticalBar();   
  27.         bg  =  getBackground();   
  28.         display  =  getDisplay();   
  29.         addListeners();   
  30.     }   
  31.   
  32.      public   void  setImage(ImageData imageData) {   
  33.         checkWidget();   
  34.   
  35.         stopAnimationTimer();   
  36.          this .image  =   new  Image(display, imageData);   
  37.          this .imageDatas  =   null ;   
  38.          this .images  =   null ;   
  39.         redraw();   
  40.     }   
  41.   
  42.      /**   
  43.      *  @param  repeatCount 0 forever  
  44.       */    
  45.      public   void  setImages(ImageData[] imageDatas,  int  repeatCount) {   
  46.         checkWidget();   
  47.   
  48.          this .image  =   null ;   
  49.          this .imageDatas  =  imageDatas;   
  50.          this .repeatCount  =  repeatCount;   
  51.         convertImageDatasToImages();   
  52.         startAnimationTimer();   
  53.         redraw();   
  54.     }   
  55.   
  56.     @Override  
  57.      public  Point computeSize( int  wHint,  int  hHint,  boolean  changed) {   
  58.         checkWidget();   
  59.   
  60.         Image image  =  getCurrentImage();   
  61.          if  (image  !=   null ) {   
  62.             Rectangle rect  =  image.getBounds();   
  63.             Rectangle trim  =  computeTrim( 0 ,  0 , rect.width, rect.height);   
  64.              return   new  Point(trim.width, trim.height);   
  65.         }   
  66.   
  67.          return   new  Point(wHint, hHint);   
  68.     }   
  69.   
  70.     @Override  
  71.      public   void  dispose() {   
  72.          if  (image  !=   null )   
  73.             image.dispose();   
  74.   
  75.          if  (images  !=   null )   
  76.              for  ( int  i  =   0 ; i  <  images.length; i ++ )   
  77.                 images[i].dispose();   
  78.   
  79.          super .dispose();   
  80.     }   
  81.   
  82.      protected   void  paint(Event e) {   
  83.         Image image  =  getCurrentImage();   
  84.          if  (image  ==   null )   
  85.              return ;   
  86.   
  87.         GC gc  =  e.gc;   
  88.         gc.drawImage(image, origin.x, origin.y);   
  89.   
  90.         gc.setBackground(bg);   
  91.         Rectangle rect  =  image.getBounds();   
  92.         Rectangle client  =  getClientArea();   
  93.          int  marginWidth  =  client.width  -  rect.width;   
  94.          if  (marginWidth  >   0 ) {   
  95.             gc.fillRectangle(rect.width,  0 , marginWidth, client.height);   
  96.         }   
  97.          int  marginHeight  =  client.height  -  rect.height;   
  98.          if  (marginHeight  >   0 ) {   
  99.             gc.fillRectangle( 0 , rect.height, client.width, marginHeight);   
  100.         }   
  101.     }   
  102.   
  103.      void  addListeners() {   
  104.         hBar.addListener(SWT.Selection,  new  Listener() {   
  105.              public   void  handleEvent(Event arg0) {   
  106.                 hscroll();   
  107.             }   
  108.         });   
  109.         vBar.addListener(SWT.Selection,  new  Listener() {   
  110.              public   void  handleEvent(Event arg0) {   
  111.                 vscroll();   
  112.             }   
  113.         });   
  114.         addListener(SWT.Resize,  new  Listener() {   
  115.              public   void  handleEvent(Event e) {   
  116.                 resize();   
  117.             }   
  118.         });   
  119.         addListener(SWT.Paint,  new  Listener() {   
  120.              public   void  handleEvent(Event e) {   
  121.                 paint(e);   
  122.             }   
  123.         });   
  124.     }   
  125.   
  126.      void  hscroll() {   
  127.         Image image  =  getCurrentImage();   
  128.          if  (image  !=   null ) {   
  129.              int  hSelection  =  hBar.getSelection();   
  130.              int  destX  =   - hSelection  -  origin.x;   
  131.             Rectangle rect  =  image.getBounds();   
  132.             scroll(destX,  0 ,  0 ,  0 , rect.width, rect.height,  false );   
  133.             origin.x  =   - hSelection;   
  134.         }   
  135.     }   
  136.   
  137.      void  vscroll() {   
  138.         Image image  =  getCurrentImage();   
  139.          if  (image  !=   null ) {   
  140.              int  vSelection  =  vBar.getSelection();   
  141.              int  destY  =   - vSelection  -  origin.y;   
  142.             Rectangle rect  =  image.getBounds();   
  143.             scroll( 0 , destY,  0 ,  0 , rect.width, rect.height,  false );   
  144.             origin.y  =   - vSelection;   
  145.         }   
  146.     }   
  147.   
  148.      void  resize() {   
  149.         Image image  =  getCurrentImage();   
  150.          if  (image  ==   null )   
  151.              return ;   
  152.   
  153.         Rectangle rect  =  image.getBounds();   
  154.         Rectangle client  =  getClientArea();   
  155.         hBar.setMaximum(rect.width);   
  156.         vBar.setMaximum(rect.height);   
  157.         hBar.setThumb(Math.min(rect.width, client.width));   
  158.         vBar.setThumb(Math.min(rect.height, client.height));   
  159.          int  hPage  =  rect.width  -  client.width;   
  160.          int  vPage  =  rect.height  -  client.height;   
  161.          int  hSelection  =  hBar.getSelection();   
  162.          int  vSelection  =  vBar.getSelection();   
  163.          if  (hSelection  >=  hPage) {   
  164.              if  (hPage  <=   0 )   
  165.                 hSelection  =   0 ;   
  166.             origin.x  =   - hSelection;   
  167.         }   
  168.          if  (vSelection  >=  vPage) {   
  169.              if  (vPage  <=   0 )   
  170.                 vSelection  =   0 ;   
  171.             origin.y  =   - vSelection;   
  172.         }   
  173.         redraw();   
  174.     }   
  175.   
  176.      void  convertImageDatasToImages() {   
  177.         images  =   new  Image[imageDatas.length];   
  178.   
  179.          //  Step 1: Determine the size of the resulting images.    
  180.          int  width  =  imageDatas[ 0 ].width;   
  181.          int  height  =  imageDatas[ 0 ].height;   
  182.   
  183.          //  Step 2: Construct each image.    
  184.          int  transition  =  SWT.DM_FILL_BACKGROUND;   
  185.          for  ( int  i  =   0 ; i  <  imageDatas.length; i ++ ) {   
  186.             ImageData id  =  imageDatas[i];   
  187.             images[i]  =   new  Image(display, width, height);   
  188.             GC gc  =   new  GC(images[i]);   
  189.   
  190.              //  Do the transition from the previous image.    
  191.              switch  (transition) {   
  192.              case  SWT.DM_FILL_NONE:   
  193.              case  SWT.DM_UNSPECIFIED:   
  194.                  //  Start from last image.    
  195.                 gc.drawImage(images[i  -   1 ],  0 ,  0 );   
  196.                  break ;   
  197.              case  SWT.DM_FILL_PREVIOUS:   
  198.                  //  Start from second last image.    
  199.                 gc.drawImage(images[i  -   2 ],  0 ,  0 );   
  200.                  break ;   
  201.              default :   
  202.                  //  DM_FILL_BACKGROUND or anything else,   
  203.                  //  just fill with default background.    
  204.                 gc.setBackground(bg);   
  205.                 gc.fillRectangle( 0 ,  0 , width, height);   
  206.                  break ;   
  207.             }   
  208.   
  209.              //  Draw the current image and clean up.    
  210.             Image img  =   new  Image(display, id);   
  211.             gc.drawImage(img,  0 ,  0 , id.width, id.height, id.x, id.y, id.width,   
  212.                     id.height);   
  213.             img.dispose();   
  214.             gc.dispose();   
  215.   
  216.              //  Compute the next transition.   
  217.              //  Special case: Can't do DM_FILL_PREVIOUS on the   
  218.              //  second image since there is no "second last"   
  219.              //  image to use.    
  220.             transition  =  id.disposalMethod;   
  221.              if  (i  ==   0   &&  transition  ==  SWT.DM_FILL_PREVIOUS)   
  222.                 transition  =  SWT.DM_FILL_NONE;   
  223.         }   
  224.     }   
  225.   
  226.     Image getCurrentImage() {   
  227.          if  (image  !=   null )   
  228.              return  image;   
  229.   
  230.          if  (images  ==   null )   
  231.              return   null ;   
  232.   
  233.          return  images[current];   
  234.     }   
  235.   
  236.      void  startAnimationTimer() {   
  237.          if  (images  ==   null   ||  images.length  <   2 )   
  238.              return ;   
  239.   
  240.          final   int  delay  =  imageDatas[current].delayTime  *   10 ;   
  241.         display.timerExec(delay, animationTimer  =   new  Runnable() {   
  242.              public   void  run() {   
  243.                  if  (isDisposed())   
  244.                      return ;   
  245.   
  246.                 current  =  (current  +   1 )  %  images.length;   
  247.                 redraw();   
  248.   
  249.                  if  (current  +   1   ==  images.length  &&  repeatCount  !=   0    
  250.                          &&   -- repeatCount  <=   0 )   
  251.                      return ;   
  252.                 display.timerExec(delay,  this );   
  253.             }   
  254.         });   
  255.     }   
  256.   
  257.      void  stopAnimationTimer() {   
  258.          if  (animationTimer  !=   null )   
  259.             display.timerExec( - 1 , animationTimer);   
  260.     }   
  261. }   
/** 
 * 负责显示各种格式的图片
 * 
 *  @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[i].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[i];
            images[i]  =   new  Image(display, width, height);
            GC gc  =   new  GC(images[i]);

             //  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);
    }
} 



测试程序

Java代码 复制代码  收藏代码
  1. public   class  ImageCanvasTest {   
  2.      public   static   void  main(String[] args) {   
  3.         Display display  =   new  Display();   
  4.          final  Shell shell  =   new  Shell(display);   
  5.         ImageViewer ic  =   new  ImageViewer(shell);   
  6.   
  7.         shell.setLayout( new  FillLayout());   
  8.         FileDialog dialog  =   new  FileDialog(shell, SWT.OPEN);   
  9.         dialog.setText( " Open an image file or cancel " );   
  10.         String string  =  dialog.open();   
  11.   
  12.         ImageLoader loader  =   new  ImageLoader();   
  13.         ImageData[] imageDatas  =  loader.load(string);   
  14.          if  (imageDatas.length  ==   0 )   
  15.              return ;   
  16.          else   if  (imageDatas.length  ==   1 ) {   
  17.             ic.setImage(imageDatas[ 0 ]);   
  18.         }  else  {   
  19.             ic.setImages(imageDatas, loader.repeatCount);   
  20.         }   
  21.   
  22.         ic.pack();   
  23.         shell.pack();   
  24.         shell.open();   
  25.          while  ( ! shell.isDisposed()) {   
  26.              if  ( ! display.readAndDispatch())   
  27.                 display.sleep();   
  28.         }   
  29.         display.dispose();   
  30.     }   
  31. }   
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动画了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值