##
EJEMPLO DE ANIMACION

> Tu navegador no entiende la marca <APPLET>. La imagen siguiente es la reproducción de la apariencia del applet en pantalla:

Este es un ejemplo de un applet, Animacion.java, que crea un thread de animación que nos presenta el globo terráqueo en rotación. Aquí podemos ver que estamos creando un thread de sí mismo, concurrencia. Además, animacion.start() llama al start() del thread, no del applet, que automáticamente llamará a run():

    import java.awt.*;
    import java.applet.Applet;

    public class Animacion extends Applet implements Runnable {
        Image imagenes[];
        MediaTracker tracker;
        int indice = 0;
        Thread animacion;

        int maxAncho,maxAlto;
        Image offScrImage; // Componente off-screen para doble buffering
        Graphics offScrGC;

        // Nos indicará si ya se puede pintar
        boolean cargado = false;

        // Inicializamos el applet, establecemos su tamaño y
        // cargamos las imágenes
        public void init() {
            // Establecemos el supervisor de imágenes
            tracker = new MediaTracker( this );
            // Fijamos el tamaño del applet
            maxAncho = 100;
            maxAlto = 100;
            imagenes = new Image[36];

            // Establecemos el doble buffer y dimensionamos el applet
            try {
                offScrImage = createImage( maxAncho,maxAlto );
                offScrGC = offScrImage.getGraphics();
                offScrGC.setColor( Color.lightGray );
                offScrGC.fillRect( 0,0,maxAncho,maxAlto );
                resize( maxAncho,maxAlto );
            } catch( Exception e ) {
                e.printStackTrace();
                }

            // Cargamos las imágenes en un array
            for( int i=0; i < 36; i++ )
                {
                String fichero =
                    new String( "Tierra"+String.valueOf(i+1)+".gif" );
                imagenes[i] = getImage( getDocumentBase(),fichero );
                // Registramos las imágenes con el tracker
                tracker.addImage( imagenes[i],i );
                }

            try {
                // Utilizamos el tracker para comprobar que todas las
                // imágenes están cargadas
                tracker.waitForAll();
            } catch( InterruptedException e ) {
                ;
                }
            cargado = true;
            }

        // Pintamos el fotograma que corresponda
        public void paint( Graphics g ) {
            if( cargado )
                g.drawImage( offScrImage,0,0,this );
            }

        // Arrancamos y establecemos la primera imagen
        public void start() {
            if( tracker.checkID( indice ) )
                offScrGC.drawImage( imagenes[indice],0,0,this );
            animacion = new Thread( this );
            animacion.start();
            }

        // Aquí hacemos el trabajo de animación
        // Muestra una imagen, para, muestra la siguiente...
        public void run() {
            // Obtiene el identificador del thread
            Thread thActual = Thread.currentThread();

            // Nos aseguramos de que se ejecuta cuando estamos en un
            // thread y además es el actual
            while( animacion != null  &&  animacion == thActual )
                {
                if( tracker.checkID( indice ) )
                    {
                    // Obtenemos la siguiente imagen
                    offScrGC.drawImage( imagenes[indice],0,0,this );
                    indice++;
                    // Volvemos al principio y seguimos, para el bucle
                    if( indice >= imagenes.length )
                        indice = 0;
                    }

                // Ralentizamos la animación para que parezca normal
                try {
                    animacion.sleep( 200 );
                } catch( InterruptedException e ) {
                    ;
                    }
                // Pintamos el siguiente fotograma
                repaint();
                }
            }
        }

En el ejemplo podemos observar más cosas. La variable `thActual` es propia de cada thread que se lance, y la variable `animacion` la estarán viendo todos los threads. No hay duplicidad de procesos, sino que todos comparten las mismas variables; cada thread, sin embargo, tiene su pila local de variables, que no comparte con nadie y que son las que están declaradas dentro de las llaves del método run().

La excepción InterruptedExcepcion salta en el caso en que se haya tenido al thread parado más tiempo del debido. Es imprescindible recoger esta excepción cuando se están implementando threads, tanto es así, que en el caso de no recogerla, el compilador generará un error.

|  | ##### [Anterior] [Indice] [Siguiente]