| Log In | Not a Member? |
Contact ADC
|
|
![]() |
|
|
| Previous Section | Table of Contents | Next Section |
Module 5- Custom Media Controllers in QTJContents Overview In this module, we will learn how to QuickTime's new button classes to offer the user an alternative to the standard QuickTime controller. This will allow us to present our own custom UI to control the playback of our zebra movie. Introduction to QuickTime Controllers Quicktime has a standard controller that allows the user to interact with the movie and perform tasks such as adjusting the volume, starting and stopping the movie, and navigating to points within the movie. This standard controller looks like this:
Using the standard controller is very simple. If you use a class such as QTPlayer, you get standard controller without any additional effort. Some applications, however, do not want to use the standard controller, either because it presents more functionality than is needed or because the developer wants to present an interface that is more consistent with the rest of the application. In either case, it is possible to create a custom controller that controls the playback of a movie. In this module, we will examine the ReleaseButton class and use it to present our own playback controls. This project is based on the previous module and assumes that you have completed it. If you would like to download a completed copy of the module 4, you may do so. We have renamed the main class to "Zoo5" and changed all instances of previous module classes to prevent confusion. Other than that, we do not need to modify the main class file. Click here to see the main source file Zoo5.java. In this example, we will be creating three different buttons, a play button, a stop button, and a rewind button. These buttons function in a very specific manner. If your browser supports JavaScript, you my experiment with the functionality of the these buttons using the controller mockup below:
As we recall from previous modules, when the user launches our program, the movie starts playing immediately. In order for the controller to be synchronized with the movie, we need to ensure that the initial state of the play button indicates that the movie is playing. This is indicated by a blue highlight color in the play triangle. Each button has a pressed state that is shown when the button is clicked. When the stop button is pressed, the movie will stop playing. We need to indicate this by adding a blue highlight color in the stop button square. We also need to make sure that we remove the active indicator from the play button. Thus, the button has the following states:
Note that the Rewind button does not have an active state. It rewinds the movie to the beginning of the media with a single click. If the movie was playing before the rewind button is pressed, the movie will begin playback at the beginning of the movie. If the movie was stopped, the movie will rewind and remain stopped. Before we start implementing our controller, we need to modify our underlying architecture. Currently, we have been doing most of our work in our AnimalPane class. This has been acceptable for previous modules, but before we add more functionality, we need to start working on making our foundation solid. We create a new file and save it as ZooPane.java. In this file, we will define a new abstract class called ZooPane that enforces a specific interface:
This class will be the superclass of AnimalPane. In future modules, we will have multiple classes that use this interface- not just AnimalPane. We move the getCompositor( ) routine and the declaration of the compositor data member down to this class, and add two additional methods start( ) and stop( ). These methods are like master control switches that can start and stop all activity in a given compositor as well as associate or disassociate the controller with the movie. Now we need to make the appropriate changes to AnimalPane. Modifying AnimalPane's Inheritance Since we have created a base class for AnimalPane, we now need to modify that file to implement the new interface:
First, we add the keyword "extends" and the class ZooPane after the declaration of the AnimalPane class. Now that we have inserted the ZooPane base class, we must implement its two abstract methods, start( ) and stop( ), We place these after our constructor, and before the playSound( ) method. We leave these two routines stubbed out for now. We will provide an implementation later as we get farther along with this module. Finally, we remove the getCompositor( ) call and the compositor data member since we moved these to our base class. Now that we have made these small modifications, we are ready to start making our controller. Now we are nearly ready to start working on our controller. First, we must do some additional housekeeping. We have a lot of new code to write, and no where to put it except in our constructor which is starting to get a little bit unruly.
Next, we declare our addMovie( ) method. This method is protected and takes five parameters, the string URL to the movie, the layer of the compositor in which the movie will be displayed, and the x and y coordinate positions of the movie within the compositor. Once this method is declared, we paste the source code in the clipboard from our constructor into the body of this method. We modify the hard-coded path of the movie file and replace it with the moviePath variable. Adding Image Loading Utility Code Previous versions of this module drew the Zebra image directly within the AnimalPane constructor. In this step, we will be replacing this code with a utility function which we will also use to draw the images associated with our custom controller:
In order to move the image loading and drawing code into its own method, we select the code in the constructor (highlighted above in red) and cut it to the clipboard. We then replace our code with a call to our new utility class we will write called makePresenterFromFile( ). Our utility method will take a string parameter representing the url of the file to be presented and return an ImagePresenter object that is capable of drawing the image. We declare a ImagePresenter data member, and assign it to the result of our utility function, passing the URL of our zebra image file to the procedure. Next, we declare our utility function immediately following our constructor. We declare our function with the following signature: public ImagePresenter makePresenterFromFile( String name ) The body of our method is in a try / catch block. We then paste the code that we copied from the constructor and modify it slightly to work in our method. We change the parameter of the GraphicsImporterDrawer constructor from a static string to the parameter passed in our method. We also modify the code to return the ImagePresenter object from the method. Now that we have made a specific method for our custom controller code, it is time to load all of our media for our controller via our utility function:
In the next section, we will create our custom buttons. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Previous Section | Table of Contents | Next Section |