##
LA CLASE MediaTracker

Si nuestro applet tiene que tratar con imágenes almacenadas en ficheros gif/jpeg, tendremos que recurrir a la clase MediaTracker. Esta clase proporciona muchos métodos para manejar objetos multimedia y grupos de objetos.

### Manejo de Imágenes para Animación

Combinando MediaTracker con la técnica de doble-buffering, se pueden conseguir animaciones. Estos son algunos métodos de MediaTracker útiles para ver gráficos

    void addImage( Image img,int id )

> Marca la imagen como parte de un grupo de identificadores `id`.

    boolean checkID( int id )

> Comprueba las imágenes pertenecientes al grupo `id`. Devuelve true si han sido cargadas todas, o false en otro caso (no carga los ficheros que falten). Se utiliza para saber cuando se han cargado todas las imágenes que componen una animación, antes de echarla a andar sobre la pantalla.

    boolean checkID( int id,boolean load )

> Comprueba las imágenes pertenecientes al grupo `id`. Devuelve true si han sido cargadas todas, o false en otro caso. Carga las imágenes que falten si `load` es true.

    boolean checkAll( boolean load )

> Comprueba todas las imágenes. Devuelve true si todas están cargadas, o false en otro caso. Carga las imágenes que falten si `load` es true.

    void waitForID( int id )

> Espera a que se carguen todas las imágenes del grupo `id`.

    void waitForAll()

> Espera a que se carguen todas las imágenes.

Se debería utilizar addImage() con cada imagen que necesite un applet. MediaTracker sólo supervisa imágenes asociadas mediante el método addImage().

Si se quiere saber si un determinado gráfico ha sido cargado, se pueden utilizar los métodos check. Si se quiere que un gráfico sea cargado antes de hacer cualquier otra cosa, usar los métodos waitFor. El uso de estos métodos es especialmente útil ya que cuando realizamos la carga de una imagen con getImage(), esta carga se realiza en un thread aparte del de nuestro applet, con lo cual, aunque la imagen se encuentre en el otro lado del mundo, getImage() devuelve inmediatamente el control con lo cual podemos comenzar la ejecución de la animación, sin haberse cargado todavía todas las imágenes.

### Creación de un Objeto MediaTracker

Los objetos MediaTracker necesitan saber qué ImageObserver verá las imágenes que se están supervisando. Para los applets, el ImageObserver es el propio applet:

    miTracker = new MediaTracker( this );

Ahora ya se puede usar el objeto `miTracker` para manejar todas las imágenes de este applet.

### Ejemplo de animación

Veamos ahora un ejemplo de animación, Taza.java. Utilizaremos MediaTracker para asegurarnos de que se cargan todas las imágenes. De este modo, cuando se ejecute la animación, no se verá parpadeo o que falta algún fotograma.

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

Y el código siguiente es el que corresponde a la animación anterior:

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

    public class Taza extends Applet {
        Image Images[];
        MediaTracker tracker;
        int index = 0;
        int maxAncho,maxAlto;

        // Componentes off-screen para el doble buffering
        Image offScrImage;
        Graphics offScrCG;
        boolean cargado = false;

        // Inicializa el applet. Establece el tamaño y carga las imágenes
        public void init() {
            // Establece el supervisor de imágenes y dimensiones
            tracker = new MediaTracker( this );
            maxAncho = 78;
            maxAlto = 128;
            imagenes = new Image[6];

            // Establece el doble buffer y cambia el tamaño del applet
            try {
                offScrImage = createImage( maxAnho,maxAlto );
                offScrCG = offScrImage.getGraphics();
                offScrCG.setColor( Color.lightGray );
                offScrCG.fillRect( 0,0,maxAncho,maxAlto );
                resize( maxAncho,maxAlto );
                }
            catch( exception e ) {
                e.printStackTrace();
                }

            // Carga las imágenes en un array
            for( int i=0; i < 33; i++ )
                {
                String imageFich =
                    new String( "taza"+String.valueOf(i+1)+".gif" );
                imagenes[i] = getImage( getDocumentBase(),imageFich );
                // Pasamos esta imagen al tracker
                tracker.addImage( imagenes[i],i );
                }

            try {
                // Utilizamos el tracker para asegurar que se
                // cargaran todas las imágenes
                tracker.waitForAll();
                }
            catch( InterruptedException e ) {
                }
            cargado = true;
            }

        // Pinta el fotograma actual
        public void paint( Graphics g ) {
            if( cargado )
                {
                // Copia del doble buffer a la pantalla
                g.drawImage( offScrImage,0,0,this );
                // Hacemos una pausa y cogemos la siguiente imagen
                timerloop();
                }
            }

        // Establecemos la primera imagen
        public void start() {
            index = 0;

            if( tracker.checkID( index ) )
                // Pintamos en el doble buffer
                offScrCG.drawImage( imagenes[index],0,0,this );
            }

        // Actualiza los fotogramas para que avance la animación
        public void timerloop() {
            // Se asegura que la imagen esté presente y la mete en el buffer
            if( tracker.checkID( index ) )
                {
                // Borra el fondo y obtiene la siguiente imagen
                offScrCG.fillRect( 0,0,100,100 );
                offScrCG.drawImage( imagenes[index],0,0,this );
                index++;

                // Vuelve al principio de la animación
                if( index <= images.length )
                    index = 0;
                }
            // Bucle de retardo
            for( int retardo=0; retardo < 200000; retardo++ );
            // Dibujamos el siguiente fotograma
            repaint();
            }
        }

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