AnimalPane.java


import java.io.IOException;
import java.io.FileNotFoundException;

import quicktime.app.QTFactory;
import quicktime.app.anim.Compositor;
import quicktime.app.image.GraphicsImporterDrawer; 
import quicktime.app.image.ImagePresenter; 
import quicktime.app.image.ImageUtil;
import quicktime.app.players.MoviePresenter;
import quicktime.app.players.QTPlayer;

import quicktime.io.QTFile;
import quicktime.io.OpenMovieFile;

import quicktime.qd.QDRect;
import quicktime.qd.QDGraphics;
import quicktime.qd.QDColor; 
import quicktime.qd.QDConstants; 

import quicktime.std.image.Matrix;
import quicktime.std.StdQTConstants;
import quicktime.std.movies.Movie; 

import quicktime.QTSession;
import quicktime.QTException; 

/**
 * QTZoo Module 5 - Custom Movie Controllers
 *
 * @author Michael Hopkins
 * @author Levi Brown
 * @author Apple Computer, Inc.
 * @version 5.0 11/15/2000
 *
 */
public class AnimalPane extends ZooPane
{
   /**
    *  Public default constructor
    *  Creates the map button, and sets up the listeners
    */
    public AnimalPane()
    {
        QDRect size = new QDRect(Zoo4.WIDTH, Zoo4.HEIGHT);
        try
        {
            // Module 4 adds support for sounds...
            loadSound("data/zebra/Zebra.au");

            QDGraphics gw = new QDGraphics( size );			// create a new graphics object
            compositor = new Compositor( gw, QDColor.white, 30, 1 );
		
            QTFile imageFile = new QTFile( 
                   QTFactory.findAbsolutePath( "data/zebra/ZebraBackground.jpg" ));
            GraphicsImporterDrawer drawer = new GraphicsImporterDrawer( imageFile );
            ImagePresenter presenter = ImagePresenter.fromGraphicsImporterDrawer( drawer );
            presenter.setLocation( 110, 110 );              // set location of movie within compositor
            compositor.addMember( presenter, 3 );           // add image presenter to compositor in 2nd layer
			
            addText( "data/zebra/Zebra.txt", 2, 15, 160, 415, 220 );

            addMovie( "data/zebra/Zebra.mov", 1, 0, 0 );    // start movie
	
			playSound();
        }
        catch( IOException e )                              // catch any errors
        {
            e.printStackTrace();
        }
        catch ( QTException e )
        {
            e.printStackTrace();
        }
    }

   /**
    * Called to do any setup after being set as the client of the QTCanvas.
    * May be used to start effects running, movies playing, etc.
    */
    public void start()
    {
        buttonController.addQTMouseListener(buttonActivator);
        try
        {
            stopButton.setCurrentImage( stopRel );      // Stop button should not have focus
            playButton.setCurrentImage( playPlaying );  // Play button should get focus (blue arrow)
            playButton.setReleasedImage( playPlaying );
        }
        catch( QTException e )
        {
            e.printStackTrace();
        }
        try
        {
            md.setRate(1);                              // start the player
        }
        catch( QTException e )
        {
            e.printStackTrace();
        }
        compositor.getTimer().setRate(1);               // start the compositor
    }

   /**
    * Called to do clean up after being removed as the client of the QTCanvas.
    * Should be used to stop effects running, movies playing, etc.
    */
    public void stop()
    {
        buttonController.removeQTMouseListener(buttonActivator);
        compositor.getTimer().setRate(0);
        try
        {
            md.setRate(0);
        }
        catch( QTException e )
        {
            e.printStackTrace();
        }
    }

   /**
    * Creates a Movie from the specified path and adds it
    * to the compositor in the hardcoded location.
    * @param moviePath the relative path to the movie file to add.
    * @param layer, the layer of the compositor to add the movie to.
    * @param x the x coordinate location.
    * @param y the y coordinate location.
    * @see #makeMovie
    */
    protected void addMovie( String moviePath, int layer, int x, int y)
    {
        try
        {
            Movie m = makeMovie( new QTFile( QTFactory.findAbsolutePath( moviePath )));
            md = new MoviePresenter(m);
            md.setLocation(x, y);
            // Add the Movie Controls
			
            playRel     = MakePresenterFromFile( "data/Play.jpg" );         // Play >
            playPress   = MakePresenterFromFile( "data/PlayPressed.jpg" );
            playPlaying = MakePresenterFromFile( "data/Playing.jpg" );
            playButton = new MovieButton( playRel, playPress, playPlaying );
            playButton.setLabel("Play");
            playButton.setLocation( x + 68, y + 152 );
			
            stopRel      = MakePresenterFromFile( "data/Stop.jpg" );        // Stop []
            stopPress    = MakePresenterFromFile( "data/StopPressed.jpg" );
            stopDeactive = MakePresenterFromFile( "data/Stopped.jpg" );
            stopButton  = new MovieButton( stopRel, stopPress, stopDeactive );
            stopButton.setLabel("Stop");
            stopButton.setLocation( x + 136, y + 152 );
			
            rewRel      = MakePresenterFromFile( "data/Rewind.jpg" );      // Rewind <<
            rewPress    = MakePresenterFromFile( "data/RewindPressed.jpg" );
            rewDeactive = MakePresenterFromFile( "data/Rewind.jpg" );
            rewindButton = new MovieButton( rewRel, rewPress, rewDeactive );
            rewindButton.setLabel( "Rewind" );
            rewindButton.setLocation( x, y + 152 );
			
            ButtonListener bl = new ButtonListener();                     // create a new listener for the buttons
			
            playButton.addActionListener(bl);
            stopButton.addActionListener(bl);
            rewindButton.addActionListener(bl);
			
            compositor.addMember(md, layer);                              // add the movie presenter
            compositor.addMember(playButton);                             //	 and buttons to the compositor
            compositor.addMember(stopButton);
            compositor.addMember(rewindButton);
			
            buttonController = new QTMouseTargetController(false);	
            buttonController.addMember(playButton);
            buttonController.addMember(stopButton);
            buttonController.addMember(rewindButton);
		
            compositor.addController (buttonController);
            buttonActivator = new ButtonActivator();
			
            md.setRate(1);                                                // start the movie		
        }
        catch(QTException exc)
        {
            exc.printStackTrace();
        }
        catch( IOException exc )
        {
            exc.printStackTrace();
        }	
    }

   /**
    * Reads a text file from the disk and displays it in the compositor
    * @param textPath the relative path where the text is located
    * @param layer, the layer of the compositor to add the text to.
    * @param x the x coordinate location.
    * @param y the y coordinate location.
    * @param width the width of the area to display the text.
    * @param height the height of the area to display the text.
    */
    protected void addText( String textPath, int layer, int x, int y, int width, int height )
    {
        try
        {
            TextPresenter text = new TextPresenter( textPath, new Dimension( width, height ));
			
            ImagePresenter presenter = text.getPresenter();
            Matrix theMatrix = new Matrix();
            theMatrix.translate( (float) x, (float) y );
            presenter.setMatrix( theMatrix );
            compositor.addMember( presenter, layer );
        }
        catch( QTException e )
        {
            e.printStackTrace();
        }
        catch( FileNotFoundException e )
        {
            e.printStackTrace();
        }	
    }	// MODULE 3 Addition

   /**
    *  Plays the sound file associated with the current AnimalPane
    */
    public void playSound()
    {
        if( player == null )
            return;

        try
        {
            player.setTime(0);			//Start the sound at the beginning
            player.startTasking(); 		//Make sure the player gets time to play the sound
            player.setRate(1); 			//Start playing
        }
        catch( QTException e )
        {
            e.printStackTrace();
        }
    }

   /**
    * Loads the specified sound file from disk and prepares it for playing
    */
    protected void loadSound( String soundPath )
    {
        try
        {
            String soundLocation = QTFactory.findAbsolutePath( soundPath ).getPath();
            //this call works with a file://, http://, rtsp://located movie
            player = (QTPlayer)QTFactory.makeDrawable( "file://" + soundLocation );
        }
        catch( IOException e )
        {
            e.printStackTrace();
        }
        catch( QTException e )
        {
            e.printStackTrace();
        }
    }	

   /**
    * Opens the movie file and sets it up to be played.
    * @param f a QTFile representing the movie to initialize.
    * @return the movie, ready to play
    */
    protected Movie makeMovie( QTFile f ) throws IOException, QTException
    {
        OpenMovieFile movieFile = OpenMovieFile.asRead(f);
        Movie m = Movie.fromFile( movieFile );
        m.getTimeBase().setFlags( StdQTConstants.loopTimeBase );// we want the movie to loop	
        return m;	
    }
		
    protected QTPlayer player;
    protected MoviePresenter md;
}