|
GIFアニメーションを表示するカスタムCanvasクラス
GIFアニメーションを表示するウィジェットです。Canvasクラスを継承して作ったクラスにGIFアニメーションをスレッドで表示するための仕組みを実装してあります。使い方は、GIFCanvasのコンストラクタにファイル名を指定してインスタンスを生成し、startAnimation()、stopAnimation()でGIFアニメーションの開始と停止を行えます。
GIFCanvas c = new GIFCanvas(shell, SWT.NONE, "earth.gif");
c.startAnimation();
c.stopAnimation();
スクリーンショット
ソースコード (GIFCanvasTest.java)
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
public class GIFCanvasTest {
private GIFCanvas gifc1;
public static void main(String[] args) {
new GIFCanvasTest();
}
public GIFCanvasTest() {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("GIFCanvasTest");
shell.setLayout(new GridLayout(3, false));
gifc1 = new GIFCanvas(shell, SWT.BORDER, "earth.gif");
Button startButton1 = new Button(shell, SWT.PUSH);
startButton1.setText("Start");
startButton1.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
gifc1.startAnimation();
}
});
Button stopButton1 = new Button(shell, SWT.PUSH);
stopButton1.setText("Stop");
stopButton1.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e) {
gifc1.stopAnimation();
}
});
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
ソースコード (GIFCanvas.java)
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
public class GIFCanvas extends Canvas {
private boolean isRunning = false;
private ImageLoader loader;
private GC canvasGC;
private Display display;
private int width;
private int height;
private Image initialImage;
private int imageDataIndex = 0;
private Thread thread = null;
private Image image;
public GIFCanvas(Composite parent, int style, String filename) {
super(parent, style);
loader = new ImageLoader();
loader.load(filename);
width = loader.logicalScreenWidth;
height = loader.logicalScreenHeight;
display = parent.getDisplay();
canvasGC = new GC(this);
initialImage = new Image(display, loader.data[0]);
addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
e.gc.setBackground(getBackground());
e.gc.fillRectangle(0, 0, width, height);
e.gc.drawImage(initialImage, 0, 0);
}
});
Shell shell = parent.getShell();
shell.addShellListener(new ShellAdapter(){
public void shellClosed(ShellEvent e) {
isRunning = false;
if (thread != null) {
while (thread.isAlive()) {
if (!display.readAndDispatch()) display.sleep();
}
}
e.doit = true;
}
});
}
public synchronized void startAnimation() {
if (isRunning) {
return;
}
isRunning = true;
thread = new AnimationThread();
thread.start();
}
public synchronized void stopAnimation() {
isRunning = false;
}
public synchronized void dispose() {
isRunning = false; // stop any animation in progress
if (image != null){
image.dispose();
}
if (canvasGC != null){
canvasGC.dispose();
}
initialImage.dispose();
super.dispose();
}
public Point computeSize(int wHint, int hHint, boolean changed) {
return super.computeSize(width, height, changed);
}
class AnimationThread extends Thread {
public void run() {
int numImage = loader.data.length;
//repeatCountを使う場合に必要
//int repeatCount = loader.repeatCount;
int width = loader.logicalScreenWidth;
int height = loader.logicalScreenHeight;
Image offScreenImage = new Image(display, width, height);
GC offScreenImageGC = new GC(offScreenImage);
Color bgcolor = canvasGC.getBackground();
offScreenImageGC.setBackground(bgcolor);
offScreenImageGC.fillRectangle(0, 0, width, height);
try {
while (isRunning) {
ImageData imageData = loader.data[imageDataIndex];
image = new Image(display, imageData);
offScreenImageGC.drawImage(image, imageData.x, imageData.y);
canvasGC.drawImage(offScreenImage, 0, 0);
//それぞれイメージには遅延時間が設定されており
//その時間だけ待機する
int delayTime = loader.data[imageDataIndex].delayTime;
//設定された遅延時間が短すぎる場合
if (delayTime < 100){
delayTime = 100;
}
try {
Thread.sleep(delayTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (imageDataIndex == numImage - 1) {
imageDataIndex = 0;
} else {
imageDataIndex++;
}
}
} finally {
offScreenImage.dispose();
offScreenImageGC.dispose();
}
}
}
}
参考リンク
以下のリンクに、GIFファイルの特徴や、GIFがどのようなデータ構造を持っているかなどの詳しい解説があります。
|
|
|