Animated GIF in SWT table / tree view cell

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

+3
source share
2 answers

After many hours of disappointing trial and error, a colleague came up with an acceptable solution. My initial approaches for implementing this in a fully standalone LabelProvider failed.

, , , LabelProvider # update() timerExec (100, Runnable() {... viewer.update()... . -, , (10% MacBook).

TableEditor: ( GIF), . TableEditor , . , . , , 25% MacBook.

  • OwnerDrawLabelProvider, GIF
  • ( ), redraw() , GIF , update()
  • , .

http://www.frightanic.com/2010/02/09/animated-gif-in-swt-tabletree-viewer-cell/.

+1

LabelProvider , viewer.update(...) , . Display.timerExec .

. , . - .

+1

Source: https://habr.com/ru/post/1727945/


All Articles