http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/DisplayananimatedGIF.htm describes how to display an animated GIF in SWT - in general. While the code works and is easily comprehensible I'm facing serious issues displaying an animated GIF in a SWT/JFace table/tree viewer cell with that technique. -> all code below
Essentially, I implemented my own OwnerDrawLabelProvider which creates an ImageLoader in paint(Event, Object) and starts an animation thread. The problem seems to be that this animation thread is not the UI thread and I don't know which GC or Display instance to use in its run() method.
I tried creating a separate GC instance in the thread's constructor - derived from event.gc - but the thread fails writing to that GC as soon as I step out of 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 need to handle this situation?
Below are the relevant code sections:
/* 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's 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 posted the same problem to the SWT newsgroup http://www.eclipse.org/forums/index.php?t=tree&th=160398