http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/DisplayananimatedGIF.htm décrit comment afficher un fichier GIF animé dans SWT - en général. Alors que le code fonctionne et est facilement compréhensible, je suis confronté à de graves problèmes d'affichage d'un fichier GIF animé dans une cellule SWT/JFace table/tree viewer avec cette technique. -> tout le code ci-dessousGIF animé dans la cellule SWT table/tree viewer
Pour l'essentiel, j'ai implémenté ma propre propriété OwnerDrawLabelProvider qui crée un ImageLoader en peinture (Event, Object) et démarre un thread d'animation. Le problème semble être que ce fil d'animation est pas le thread UI et je ne sais pas quelle instance GC ou Display à utiliser dans sa méthode run().
J'ai essayé de créer une instance distincte de GC dans le constructeur de fil - dérivé de event.gc - mais le fil n'écrit que GC dès que je fais un pas sur le débogueur ...
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
Comment dois-je gérer cette situation?
Voici les sections pertinentes du 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'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
J'ai posté le même problème dans le groupe de SWT http://www.eclipse.org/forums/index.php?t=tree&th=160398
Merci pour le pointeur, je vais y jeter un coup d'oeil. Juste pour être clair ... vous proposez de mettre en place un LabelProvider "régulier" (c.-à-d.pas OwnerDraw) pour renvoyer des images statiques le cas échéant - sur les lignes contenant des images statiques - et appeler séparément viewer.update (...) pour toutes les lignes contenant des images animées. –
Hhhmmm, c'est bien, mais j'ai encore besoin de trouver les bonnes instances Display et GC pour peindre sur ... –
Vous pouvez simplement obtenir l'affichage à partir du contrôle. GC gc = nouveau GC (myTable.getDisplay()). –