`

SWT显示GIF动态图片工具类

 
阅读更多
整理了一个工具类, 用于在SWT中显示GIF图片

/**
 * 用于显示GIF图片的util类
 * 
 * @author mark.wang
 */
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 Color bg;
	private Display display;

	public ImageViewer(Composite parent) {
		super(parent, SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE);

		bg = getBackground();
		display = getDisplay();
		addListeners();
	}

	/**
	 * @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() {
		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], 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 static void main(String[] args) {
		Display display = new Display();
		final Shell shell = new Shell(display);
		CopyOfImageViewer ic = new CopyOfImageViewer(shell);

		shell.setLayout(new FillLayout());
		FileDialog dialog = new FileDialog(shell, SWT.OPEN);
		dialog.setText(" Open an gif image file or cancel, only gif ");
		String string = dialog.open();

		ImageLoader loader = new ImageLoader();
		ImageData[] imageDatas = loader.load(string);
		ic.setImages(imageDatas, loader.repeatCount);

		ic.pack();
		shell.pack();
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}
}
分享到:
评论

相关推荐

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

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

    SWT(JFace) Menu、Bar...体验代码

    总结来说,SWT和JFace为我们提供了创建丰富用户界面的工具,包括菜单栏和下拉菜单。通过`MenuItem`类,我们可以轻松地创建不同类型的菜单项,如普通按钮、下拉菜单、复选框和单选按钮,并为它们添加事件监听器以响应...

    java 开发视图插件(View) eclipse

    在这个类中,你需要重写`createPartControl`方法,用于创建视图的 SWT 控件,以及`setFocus`方法,使得视图获取焦点时能正确响应。 ```java public class MyView extends ViewPart { @Override public void ...

    eclipse插件介绍

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

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

    有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...

    Qt的开发体会 ppt

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

    java源码包2

    有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...

    java源码包3

    有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...

    java源码包4

    有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...

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

    有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...

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

    有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码加以改进做成小工具。 Java右键弹出...

    RCP jface 数据绑定 例子和测试范例

    在提供的压缩包中,"unchecked.gif"和"checked.gif"可能是用于表示复选框状态的图形资源。在数据绑定的例子中,它们可能被用作UI反馈,展示复选框的选中或未选中状态,并且这些状态会与模型中的布尔值进行同步。 ...

    ECLIPSE RCP Develpment

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

Global site tag (gtag.js) - Google Analytics