📄 animationgif.java
字号:
package cn.com.chengang.jface.dialog.loopprogressdialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
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.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
public class AnimationGIF extends Canvas {
private Display display = Display.getDefault();
private boolean stopFlag = true;
private ImageLoader imageLoader;
private Image baseImage;
private GC baseImageGC;
private int frameTotal;
private int frame = 0;
public AnimationGIF(Composite parent, int style, ImageLoader imageLoader) {
super(parent, style | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND);
this.imageLoader = imageLoader;
frameTotal = imageLoader.data.length;// 总帧数
baseImage = new Image(display, imageLoader.data[0]);// 第一帧是底图
baseImageGC = new GC(baseImage);// 创建在第一帧上画画的画笔
addPaintListener(new PaintListener() {
public void paintControl(PaintEvent event) {
// 在画布上画出baseImage,此时的baseImage是第一帧底图和当前帧的叠加
event.gc.drawImage(baseImage, 0, 0);
}
});
run();
}
// 停止
public void stop() {
stopFlag = true;
}
// 显示动画
public void run() {
if (!stopFlag)
return;// 不能还在运行时,再次执行本方法
stopFlag = false;// 标志为正在运行
new Thread() {
public void run() {
showImages();
}
}.start();
}
private void showImages() {
while (true) {
if (stopFlag)
return;
try {// 等待一下.动态GIF文件自带信息里有每一帧的等待时间
int time = imageLoader.data[frame].delayTime;
Thread.sleep(time == 0 ? 300 : time * 10);
} catch (InterruptedException e) {}
//
if (isDisposed())
return;// 如果窗口关闭,则循环结束
// 主要做两件事:在底图上baseImage上追加新图;canvas.redraw()重绘画布
display.asyncExec(new Runnable() {
public void run() {
showNextImage();
}
});
}
}
private void showNextImage() {
// 计算当前应显示的帧:先判断前一帧是不是最后一帧,如是则归零,否则+1得到当前帧
frame = (frame == frameTotal - 1) ? 0 : frame + 1;
ImageData data = imageLoader.data[frame];// 生成帧的Image对象
// SWT.DM_UNSPECIFIED=0 未指定。本实例把它当作值2
// SWT.DM_FILL_NONE=1 什么都不做,让当前图片存在。
// SWT.DM_FILL_BACKGROUND=2 填充背景色
// SWT.DM_FILL_PREVIOUS=3 恢复上一张图片.
if (data.disposalMethod == SWT.DM_FILL_BACKGROUND) {
data.transparentPixel = -1;// 设置为无透明像素
baseImageGC.setBackground(baseImage.getBackground());
baseImageGC.fillRectangle(baseImage.getBounds());
}
Image image = new Image(display, data);// 生成当前帧图像
baseImageGC.drawImage(image, data.x, data.y);// 把当前帧叠加到第一帧的图片上
image.dispose();// 画完后image就没用了,立即释放它
if (!isDisposed())
redraw();// 画布重绘,触发PaintListener的paintControl方法
}
@Override
public void dispose() {
baseImageGC.dispose();
baseImage.dispose();
super.dispose();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -