Pregunta

http://www.java2s.com/Code /Java/SWT-JFace-Eclipse/DisplayananimatedGIF.htm describe cómo mostrar un GIF animado en SWT - en general. Mientras que el código funciona y es fácilmente comprensible que estoy enfrentando problemas serios que muestran un GIF animado en una mesa / árbol / JFace celular espectador SWT con esa técnica. -> todas siguiente código

En esencia, he implementado mi propia OwnerDrawLabelProvider que crea un ImageLoader en la pintura (Evento, Object) y comienza un hilo de animación. El problema parece ser que este hilo de animación es no el hilo de interfaz de usuario y no sé cual GC o mostrar instancia a utilizar en su método run ().

He intentado crear una instancia separada de GC en el constructor de la rosca - derivado de event.gc - pero el hilo falla escrito a tal GC tan pronto como salga del depurador ...

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 

¿Qué necesito para manejar esta situación?
A continuación se presentan las secciones de código correspondientes:

/* 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 

He publicado el mismo problema a la SWT grupo de noticias http: // www.eclipse.org/forums/index.php?t=tree&th=160398

¿Fue útil?

Solución

Después de muchas horas de frustración por ensayo y error de un compañero de trabajo le ocurrió una solución factible. Mis primeras aproximaciones a este han implementado de una forma totalmente autónoma LabelProvider fracasado estrepitosamente.

Uno de los enfoques que no funcionó fue para anular LabelProvider # update () y llamar timerExec (100, nuevo Ejecutable () {... viewer.update () ... desde dentro de ese método. La "vida" -Ciclo de que es difícil de controlar y que utiliza demasiados ciclos de CPU (10% en mi MacBook).

Una de las ideas del colega fue implementar un TableEditor personalizado: una etiqueta con una imagen (un cuadro de la animación GIF), pero no hay texto. Cada instancia TableEditor comenzaría su propio hilo en el que se actualiza la imagen de la etiqueta. Esto funciona bastante bien, pero hay un hilo separado "animación" para cada icono animado. Además, este era un asesino rendimiento, consume el 25% de la CPU en mi MacBook.

El último enfoque tiene tres bloques de construcción

  • una OwnerDrawLabelProvider que pinta o bien una imagen estática o el marco de un GIF animado
  • una rosca de animación (el fabricante de paso), llama a volver a dibujar () para la columna que contiene los archivos GIF animados y también se llama update ()
  • y proveedor de contenido del espectador que controla el hilo animación.

Los detalles en mi blog http://www.frightanic.com/2010/02/09/animated-gif-in-swt-tabletree-viewer-cell/ .

Otros consejos

¿No puedes dejar que un LabelProvider devolver diferentes imágenes y luego llamar viewer.update (...) en los elementos que desea animar. Puede utilizar Display.timerExec para obtener una devolución de llamada en lugar de tener un hilo separado.

aquí de cómo puede cambiar los colores. Usted debe ser capaz de hacer algo similar con las imágenes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top