`
Irving_wei
  • 浏览: 132564 次
  • 性别: Icon_minigender_1
  • 来自: Heaven
社区版块
存档分类
最新评论

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


测试程序

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动画了。
分享到:
评论

相关推荐

    Draw2D 模拟SWT控件之TextField、TextArea

    压缩包中的图像文件可能是用于模拟SWT控件状态的,如radiobutton_checked.gif和checkbox_checked.gif分别表示单选按钮和复选框的选中状态,而未选中状态的图片则表示它们的非选中状态。textarea_1.gif和textarea_2....

    Draw2D 模拟SWT控件之RadioButton、CheckedBox

    开发者可以通过编程逻辑控制这些图片的显示,来模拟选中和未选中的视觉效果。 实现这个功能的基本步骤包括: 1. 创建一个自定义的Draw2D图形对象,比如继承自GFShape,然后覆盖paint方法来绘制RadioButton和...

    Taking a look at SWT Images

    此外,文章还提到了动画(GIF animation),解释了如何在SWT中实现图像序列的播放,以创建动态效果。 在图像缩放(`Scaling`)部分,讲述了如何调整图像大小,以适应不同的显示需求。这通常涉及到图像的拉伸或保持...

    java创建系统托盘实现(swt和jdk6分别实现)

    `16.gif` 文件是用于图标显示的图形资源,`swt.jar` 是SWT库的依赖,它包含了SWT相关的类和方法。 总的来说,了解如何在不同环境下创建系统托盘图标对于开发跨平台的应用程序至关重要,这使得用户即使在应用程序...

    网页设计要点汇总.pdf

    * 但这时候图像是平铺的,就是背景图片不断重复,不重复的操作:在上一步显示的图片后/*.jpg ”接着按空格键(选择style,按回车)style=background-repeat(按回车)--no repeat * 把Flash背景设成透明色:先单击...

    ecshop商品套餐功能-组合套餐插件-套餐组合功能.zip

    "显示一个套餐问题修复.txt"可能是一个针对某个特定问题的修复文档,比如当系统只能显示一个套餐时,商家可以参考这个文件来解决这个问题,确保所有套餐都能正常显示。 总的来说,这个压缩包提供的资源涵盖了ECSHOP...

    eclipse插件介绍

    Green UML支持动态添加和删除类图中的关联,还可以将类图导出为jpg和gif格式。 7. **Tribix**:Tribix扩展了BIRT(Business Intelligence and Reporting Tools)的Emitter,增加了PPT和XLS格式的支持,使得BIRT报告...

    java 开发视图插件(View) eclipse

    确保将图片资源添加到项目的`icons`目录,并在`plugin.xml`中引用。 7. **HTML文档**:`ljllql.htm`和`ljllql_files`可能是一份关于如何开发Eclipse视图插件的教程或指南,里面可能包含了详细的步骤和示例代码。 ...

    ECSHOP组合套餐功能 商品套餐插件 套餐组合功能

    - **goods.swt**:可能是商品相关的一种配置文件,包含商品信息或与套餐相关的设置。 - **需要删除代码说明.txt**:这个文件提供了关于如何删除不需要的代码或功能的指南,可能是因为插件中包含了部分冗余或特定需求...

    妇科医院网站源码带手机端php整站程序

    它具有高效、跨平台的特性,允许开发者快速构建动态网页。 2. **响应式设计**:妇科医院网站源码采用了响应式布局,确保网站在不同设备上(如桌面、平板电脑、智能手机)都能自适应显示,提供良好的用户体验。 3. ...

    Qt的开发体会 ppt

    QString file = QFileDialog::getOpenFileName(this, "Select a Picture of Target File", "", "*.jpg *.png *.tif *.gif"); ``` 这行代码将弹出一个文件选择对话框,让用户选择一个图片文件。 #### 六、自定义...

    java源码包---java 源码 大量 实例

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java源码包2

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java源码包3

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java源码包4

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明...

    JAVA上百实例源码以及开源项目源代码

    摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明...

    ECLIPSE RCP Develpment

    - **MTrimmedWindow**:表示应用程序中的一个窗口,其底层的SWT shell使用SWT.SHELL_TRIM属性创建,这意味着它具有标题栏、最小化、最大化和调整大小按钮。 - **MPerspective**:表示透视图模型元素的对象。 - **...

Global site tag (gtag.js) - Google Analytics