java swt 之 图片控件

swt好像加载动态gif也得需要自己让图片跑起来,找了很长时间找到一份源码,改了改,让它更原本一点。

 

使用的话,注意gif帧速的变量,可以自己多调试调试,gif在不同的平台上速度是不一样的,就像那个跑疯了的手机测试gif一样。

 

 

package atomQQswt.ui.core;

import java.io.InputStream;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

public class ImageCanvas extends Canvas {
    
    
private ImageLoader loader;

    
protected Point origin = new Point(00);
    
protected Image image;
    
protected ImageData[] imageDatas;
    
protected Image[] images;
    
protected int current;

    
private int repeatCount;
    
private Runnable animationTimer;
 
    
private Color bg;
    
private Display display;

    
public ImageCanvas(Composite parent) {
        
super(parent, SWT.DOUBLE_BUFFERED | SWT.INHERIT_FORCE |SWT.INHERIT_DEFAULT);

      
        bg 
= getBackground();
        display 
= getDisplay();
        addListeners();
    }
    
    
/**
     * 传入路径获取图片.
     *
     * 
@param path the new image
     
*/
    
public void setImage(String path){
         loader 
= new ImageLoader();
         imageDatas 
= loader.load(path);
         
if(imageDatas.length == 0)
             
return;
         
else if(imageDatas.length == 1){
             checkWidget();

             stopAnimationTimer();
             
this.image = new Image(display, imageDatas[0]);
             
this.imageDatas = null;
             
this.images = null;
             redraw();
         }
else {
             checkWidget();

             
this.image = null;
             
this.repeatCount = loader.repeatCount;
             convertImageDatasToImages();
             startAnimationTimer();
             redraw();
             
         }
    }
    
    
/**
     * 传入InputStream获取图片.
     *
     * 
@param isin the new image
     
*/
    
public void setImage(InputStream isin){
         loader 
= new ImageLoader();
         imageDatas 
= loader.load(isin);
         
if(imageDatas.length == 0)
             
return;
         
else if(imageDatas.length == 1){
             checkWidget();

             stopAnimationTimer();
             
this.image = new Image(display, imageDatas[0]);
             
this.imageDatas = null;
             
this.images = null;
             redraw();
         }
else {
             checkWidget();

             
this.image = null;
             
this.repeatCount = loader.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(00, 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() {
        addListener(SWT.Paint, 
new Listener() {
            
public void handleEvent(Event e) {
                paint(e);
            }
        });
    }

  

    
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], 00);
                
break;
            
case SWT.DM_FILL_PREVIOUS:
                
// Start from second last image.
                gc.drawImage(images[i - 2], 00);
                
break;
            
default:
                
// DM_FILL_BACKGROUND or anything else,
                
// just fill with default background.
                gc.setBackground(bg);
                gc.fillRectangle(
00, width, height);
                
break;
            }

            
// Draw the current image and clean up.
            Image img = new Image(display, id);
            gc.drawImage(img, 
00, 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;

        
int delay = imageDatas[current].delayTime*20;
        
if (delay <5) delay = 100;
       
        
final int ms=delay;
        display.timerExec(ms, 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(ms, 
this);
            }
        });
    }

    
void stopAnimationTimer() {
        
if (animationTimer != null)
            display.timerExec(
-1, animationTimer);
    }
}

 

posted on 2011-05-04 23:18  黑暗伯爵  阅读(4641)  评论(0编辑  收藏  举报

导航