Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » animated images require no separate thread
animated images require no separate thread [message #467845] Mon, 03 August 2009 07:18 Go to next message
Viliam Durina is currently offline Viliam DurinaFriend
Messages: 13
Registered: July 2009
Junior Member
This is a multi-part message in MIME format.
--------------090109040700000006000807
Content-Type: text/plain; charset=ISO-8859-2; format=flowed
Content-Transfer-Encoding: 7bit

I rewritten the snippet "display an animated GIF" (Snippet141) in a way that it does not require separate thread for the animation. I use Display.timerExec instead - in each iteration I change the image to the next one and schedule the next iteration.

Threads are considered expensive resource, and to have one for each animation seems wastage. Other snippets with animations could be rewritten in a similar way.

Viliam

--------------090109040700000006000807
Content-Type: text/plain;
name="MySnippet.java"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="MySnippet.java"

/*********************************************************** ********************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
************************************************************ *******************/
package test;

/*
* Image example snippet: display an animated GIF
*
* For a list of all SWT example snippets see
* http://www.eclipse.org/swt/snippets/
*/
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

public class MySnippet {
static Display display;
static Shell shell;
static GC shellGC;
static Color shellBackground;
static ImageLoader loader;
static ImageData[] imageDataArray;
static Image image;
static final boolean useGIFBackground = false;

public static void main(String[] args) {
display = new Display();
shell = new Shell(display);
shell.setSize(300, 300);
shell.open();
shellGC = new GC(shell);
shellBackground = shell.getBackground();

FileDialog dialog = new FileDialog(shell);
dialog.setFilterExtensions(new String[] {"*.gif"});
String fileName = dialog.open();
if (fileName != null) {
loader = new ImageLoader();
try {
imageDataArray = loader.load(fileName);
if (imageDataArray.length > 1) {
Runnable animateRunnable = new Runnable() {
private Image offScreenImage;
private GC offScreenImageGC;
private int imageDataIndex = 0;
private ImageData imageData = imageDataArray[imageDataIndex];
int repeatCount;

// anonymous constructor
{
/* Create an off-screen image to draw on, and fill it with the shell background. */
offScreenImage = new Image(display, loader.logicalScreenWidth, loader.logicalScreenHeight);
offScreenImageGC = new GC(offScreenImage);
offScreenImageGC.setBackground(shellBackground);
offScreenImageGC.fillRectangle(0, 0, loader.logicalScreenWidth, loader.logicalScreenHeight);

/* Create the first image and draw it on the off-screen image. */
if (image != null && !image.isDisposed()) image.dispose();
image = new Image(display, imageData);
offScreenImageGC.drawImage(
image,
0,
0,
imageData.width,
imageData.height,
imageData.x,
imageData.y,
imageData.width,
imageData.height);

repeatCount = loader.repeatCount;
}

public void run() {
// if the shell is not disposed, draw the next image in animation and reschedule the runnable, otherwise
// do cleanup.
if ( ! shell.isDisposed()) {
/* Now loop through the images, creating and drawing each one
* on the off-screen image before drawing it on the shell. */
if (loader.repeatCount == 0 || repeatCount > 0) {
switch (imageData.disposalMethod) {
case SWT.DM_FILL_BACKGROUND:
/* Fill with the background color before drawing. */
Color bgColor = null;
if (useGIFBackground && loader.backgroundPixel != -1) {
bgColor = new Color(display, imageData.palette.getRGB(loader.backgroundPixel));
}
offScreenImageGC.setBackground(bgColor != null ? bgColor : shellBackground);
offScreenImageGC.fillRectangle(imageData.x, imageData.y, imageData.width, imageData.height);
if (bgColor != null) bgColor.dispose();
break;
case SWT.DM_FILL_PREVIOUS:
/* Restore the previous image before drawing. */
offScreenImageGC.drawImage(
image,
0,
0,
imageData.width,
imageData.height,
imageData.x,
imageData.y,
imageData.width,
imageData.height);
break;
}

imageDataIndex = (imageDataIndex + 1) % imageDataArray.length;
imageData = imageDataArray[imageDataIndex];
image.dispose();
image = new Image(display, imageData);
offScreenImageGC.drawImage(
image,
0,
0,
imageData.width,
imageData.height,
imageData.x,
imageData.y,
imageData.width,
imageData.height);

/* Draw the off-screen image to the shell. */
shellGC.drawImage(offScreenImage, 0, 0);

/* Reschedule the runnable after the specified delay time (adding commonly-used slow-down fudge factors). */
int ms = imageData.delayTime * 10;
if (ms < 20) ms += 30;
if (ms < 30) ms += 10;
Display.getCurrent().timerExec(ms, this);

/* If we have just drawn the last image, decrement the repeat count and start again. */
if (imageDataIndex == imageDataArray.length - 1) repeatCount--;
}
}
else {
if (offScreenImage != null && !offScreenImage.isDisposed()) offScreenImage.dispose();
if (offScreenImageGC != null && !offScreenImageGC.isDisposed()) offScreenImageGC.dispose();
if (image != null && !image.isDisposed()) image.dispose();
}
}
};

// start the runnable for the first time - it will reschedule iteself
animateRunnable.run();
}
} catch (SWTException ex) {
System.out.println("There was an error loading the GIF");
}
}

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}

--------------090109040700000006000807--
Re: animated images require no separate thread [message #481948 is a reply to message #467845] Mon, 24 August 2009 19:36 Go to previous message
Grant Gayed is currently offline Grant GayedFriend
Messages: 2151
Registered: July 2009
Senior Member
Thanks for this! I've logged
https://bugs.eclipse.org/bugs/show_bug.cgi?id=287477 .

Grant


"Viliam Durina" <viliam.durina@gmail.com> wrote in message
news:h5630n$r4v$1@build.eclipse.org...
> I rewritten the snippet "display an animated GIF" (Snippet141) in a way
that it does not require separate thread for the animation. I use
Display.timerExec instead - in each iteration I change the image to the next
one and schedule the next iteration.
>
> Threads are considered expensive resource, and to have one for each
animation seems wastage. Other snippets with animations could be rewritten
in a similar way.
>
> Viliam
>


------------------------------------------------------------ ----------------
----


>
/*********************************************************** ****************
****
> * Copyright (c) 2000, 2004 IBM Corporation and others.
> * All rights reserved. This program and the accompanying materials
> * are made available under the terms of the Eclipse Public License v1.0
> * which accompanies this distribution, and is available at
> * http://www.eclipse.org/legal/epl-v10.html
> *
> * Contributors:
> * IBM Corporation - initial API and implementation
>
************************************************************ ****************
***/
> package test;
>
> /*
> * Image example snippet: display an animated GIF
> *
> * For a list of all SWT example snippets see
> * http://www.eclipse.org/swt/snippets/
> */
> import org.eclipse.swt.*;
> import org.eclipse.swt.graphics.*;
> import org.eclipse.swt.widgets.*;
>
> public class MySnippet {
> static Display display;
> static Shell shell;
> static GC shellGC;
> static Color shellBackground;
> static ImageLoader loader;
> static ImageData[] imageDataArray;
> static Image image;
> static final boolean useGIFBackground = false;
>
> public static void main(String[] args) {
> display = new Display();
> shell = new Shell(display);
> shell.setSize(300, 300);
> shell.open();
> shellGC = new GC(shell);
> shellBackground = shell.getBackground();
>
> FileDialog dialog = new FileDialog(shell);
> dialog.setFilterExtensions(new String[] {"*.gif"});
> String fileName = dialog.open();
> if (fileName != null) {
> loader = new ImageLoader();
> try {
> imageDataArray = loader.load(fileName);
> if (imageDataArray.length > 1) {
> Runnable animateRunnable = new Runnable() {
> private Image offScreenImage;
> private GC offScreenImageGC;
> private int imageDataIndex = 0;
> private ImageData imageData = imageDataArray[imageDataIndex];
> int repeatCount;
>
> // anonymous constructor
> {
> /* Create an off-screen image to draw on, and fill it with the shell
background. */
> offScreenImage = new Image(display, loader.logicalScreenWidth,
loader.logicalScreenHeight);
> offScreenImageGC = new GC(offScreenImage);
> offScreenImageGC.setBackground(shellBackground);
> offScreenImageGC.fillRectangle(0, 0, loader.logicalScreenWidth,
loader.logicalScreenHeight);
>
> /* Create the first image and draw it on the off-screen image. */
> if (image != null && !image.isDisposed()) image.dispose();
> image = new Image(display, imageData);
> offScreenImageGC.drawImage(
> image,
> 0,
> 0,
> imageData.width,
> imageData.height,
> imageData.x,
> imageData.y,
> imageData.width,
> imageData.height);
>
> repeatCount = loader.repeatCount;
> }
>
> public void run() {
> // if the shell is not disposed, draw the next image in animation and
reschedule the runnable, otherwise
> // do cleanup.
> if ( ! shell.isDisposed()) {
> /* Now loop through the images, creating and drawing each one
> * on the off-screen image before drawing it on the shell. */
> if (loader.repeatCount == 0 || repeatCount > 0) {
> switch (imageData.disposalMethod) {
> case SWT.DM_FILL_BACKGROUND:
> /* Fill with the background color before drawing. */
> Color bgColor = null;
> if (useGIFBackground && loader.backgroundPixel != -1) {
> bgColor = new Color(display,
imageData.palette.getRGB(loader.backgroundPixel));
> }
> offScreenImageGC.setBackground(bgColor != null ? bgColor :
shellBackground);
> offScreenImageGC.fillRectangle(imageData.x, imageData.y, imageData.width,
imageData.height);
> if (bgColor != null) bgColor.dispose();
> break;
> case SWT.DM_FILL_PREVIOUS:
> /* Restore the previous image before drawing. */
> offScreenImageGC.drawImage(
> image,
> 0,
> 0,
> imageData.width,
> imageData.height,
> imageData.x,
> imageData.y,
> imageData.width,
> imageData.height);
> break;
> }
>
> imageDataIndex = (imageDataIndex + 1) % imageDataArray.length;
> imageData = imageDataArray[imageDataIndex];
> image.dispose();
> image = new Image(display, imageData);
> offScreenImageGC.drawImage(
> image,
> 0,
> 0,
> imageData.width,
> imageData.height,
> imageData.x,
> imageData.y,
> imageData.width,
> imageData.height);
>
> /* Draw the off-screen image to the shell. */
> shellGC.drawImage(offScreenImage, 0, 0);
>
> /* Reschedule the runnable after the specified delay time (adding
commonly-used slow-down fudge factors). */
> int ms = imageData.delayTime * 10;
> if (ms < 20) ms += 30;
> if (ms < 30) ms += 10;
> Display.getCurrent().timerExec(ms, this);
>
> /* If we have just drawn the last image, decrement the repeat count and
start again. */
> if (imageDataIndex == imageDataArray.length - 1) repeatCount--;
> }
> }
> else {
> if (offScreenImage != null && !offScreenImage.isDisposed())
offScreenImage.dispose();
> if (offScreenImageGC != null && !offScreenImageGC.isDisposed())
offScreenImageGC.dispose();
> if (image != null && !image.isDisposed()) image.dispose();
> }
> }
> };
>
> // start the runnable for the first time - it will reschedule iteself
> animateRunnable.run();
> }
> } catch (SWTException ex) {
> System.out.println("There was an error loading the GIF");
> }
> }
>
> while (!shell.isDisposed()) {
> if (!display.readAndDispatch()) display.sleep();
> }
> display.dispose();
> }
> }
>
Previous Topic:SWT Draw2d and system resources
Next Topic:Showing Google map in the browser widget
Goto Forum:
  


Current Time: Sat Nov 22 10:25:55 GMT 2014

Powered by FUDForum. Page generated in 0.17035 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software