http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/DisplayananimatedGIF.htm describes how to display an animated GIF in SWT - in general. Although the code works and is easy to understand, I ran into serious problems displaying an animated GIF in a table / tree view cell of SWT / JFace with this technique. → all code below
Essentially, I implemented my own OwnerDrawLabelProvider, which creates an ImageLoader in paint (Event, Object) and starts the animation stream. The problem is that this animation stream is not a user interface stream, and I don't know which GC or Display instance to use in the run () method.
I tried to create a separate GC instance in the stream constructor derived from event.gc, but the stream is not written to this GC as soon as I exit the debugger ...
Sat Jan 9 22:11:57 192.168.1.6.local.home java [25387]: CGContextConcatCTM: invalid context 0x0
2010-01-09 22: 12: 18.356 java [25387: 17b03] It does not make sense to draw an image when [NSGraphicsContext currentContext] is nil. This is a programming error. Break on _NSWarnForDrawingImageWithNoCurrentContext to debug. This will be logged only once. This may break in the future.
Sat Jan 9 22:12:41 192.168.1.6.local.home java [25387]: CGContextConcatCTM: invalid context 0x0
How do I deal with this situation?
Below are the relevant sections of the code:
/ * Called by paint (Event, Object). * /
private void paintAnimated (final Event event, final ImageLoader imageLoader) {
if (imageLoader == null || ArrayUtils.isEmpty (imageLoader.data)) {
return
}
final Thread animateThread = new AnimationThread (event, imageLoader);
animateThread.setDaemon (true);
animateThread.start ();
}
private class AnimationThread extends Thread {
private display display;
private gc gc;
private ImageLoader imageLoader;
private color background;
public AnimationThread (final Event event, final ImageLoader imageLoader) {
super ("Animation");
this.display = event.display;
/ *
* If we were to simply reference event.gc it would be reset / empty by the time it being used
* in run ().
* /
this.gc = new GC (event.gc.getDevice ());
this.imageLoader = imageLoader;
this.background = getBackground (event.item, event.index);
}
@Override
public void run () {
/ *
* Create an off-screen image to draw on, and fill it with the shell background.
* /
final Image offScreenImage =
new Image (this.display, this.imageLoader.logicalScreenWidth,
this.imageLoader.logicalScreenHeight);
final GC offScreenImageGC = new GC (offScreenImage);
offScreenImageGC.setBackground (this.background);
offScreenImageGC.fillRectangle (0, 0, this.imageLoader.logicalScreenWidth,
this.imageLoader.logicalScreenHeight);
Image image = null;
try {
/ * Create the first image and draw it on the off-screen image. * /
int imageDataIndex = 0;
ImageData imageData = this.imageLoader.data [imageDataIndex];
image = new Image (this.display, imageData);
offScreenImageGC.drawImage (image, 0, 0, imageData.width, imageData.height, imageData.x,
imageData.y, imageData.width, imageData.height);
/ *
* Now loop through the images, creating and drawing each one on the off-screen image before
* drawing it on the shell.
* /
int repeatCount = this.imageLoader.repeatCount;
while (this.imageLoader.repeatCount == 0 || repeatCount> 0) {
switch (imageData.disposalMethod) {
case SWT.DM_FILL_BACKGROUND:
/ * Fill with the background color before drawing. * /
offScreenImageGC.setBackground (this.background);
offScreenImageGC.fillRectangle (imageData.x, imageData.y, imageData.width,
imageData.height);
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)% this.imageLoader.data.length;
imageData = this.imageLoader.data [imageDataIndex];
image.dispose ();
image = new Image (this.display, imageData);
offScreenImageGC.drawImage (image, 0, 0, imageData.width, imageData.height, imageData.x,
imageData.y, imageData.width, imageData.height);
// Draw the off-screen image.
this.gc.drawImage (offScreenImage, 0, 0);
/ *
* Sleeps for the specified delay time (adding commonly-used slow-down fudge factors).
* /
try {
int ms = imageData.delayTime * 10;
if (ms I sent the same issue to the SWT newsgroup http://www.eclipse.org/forums/index.php?t=tree&th=160398