SWT图片显示,支持JPEG,GIF(动画),BMP,ICO,PNG和TIFF

SWT图片显示,支持JPEG,GIF(动画),BMP,ICO,PNG和TIFF

因为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动画了。
转载请保留 http://www.blogjava.net/xilaile/archive/2007/04/10/109547.html

你可能感兴趣的:(SWT图片显示,支持JPEG,GIF(动画),BMP,ICO,PNG和TIFF)