UNIT II - Chapter 5 - How to time the timers

Chapter 5          :           How to time the timers?

Timers are always an important part of programming. They are even more important in the mobile domain as the two of the most used applications on the mobile phone are games and auto synchronizing network enabled application. Both these types of applications are heavily dependent upon the timers for there functioning. Sensing this Sun Microsystems has included the classes Timer and TimerTask in the Mobile Information Device Profile (MIDP).

These two classes are very easy to use and enable us to perform complex timing functions. They can be used in a number of tasks like:

  • Gaming
  • Animations
  • Automatic synchronization of data from a server
  • Reminders
  • Splash screens for displaying logo of the company
  • Auto help functionality like the one in Nokia 6610

 

Thus the timing functionality is very important. We will now discuss the classes Timer and TimerTask more extensively. However before pursuing further I would like to tell you an important fact, the Timer class can not guarantee the exactness of the intervals. Thus we should not use the Timer class for very accurate time keeping tasks like the stop watch. We have given the example code for a stop watch just to make you familiar with the programming for timers.



Timer

          The Timer class is contained within the package java.util of the Mobile Information Device Profile (MIDP). The Timer class provides us with 2 types of timekeeping, namely:

  • One time execution

Timer provides one time execution for tasks like animating the splash screen or displaying the help automatically after some time, once. There are 2 methods in the Timer class which can schedule the Timer to run once, namely:

o    public void schedule (TimerTask task, Date time)

This method can be used for scheduling the specified task for execution at the specified time. If the current time is already past the time mentioned by the programmer, the task is scheduled for immediate execution.

o    public void schedule (TimerTask task, long delay)

This method schedules execution of the specified TimerTask after a specified amount of delay.

  • Repeated execution

The repeated execution of tasks is required for certain situation like the gaming applications and the auto synchronizing applications. Games generally involve animation where the changes in frames are timed through the use of Timers with repeated execution. The Timer class provides the following methods for repeated executions:

 

Fixed delay repeated executions

In this type of scheduling the tasks are scheduled to run relative to the actual time of the execution of the previous execution.

o    public void schedule (TimerTask task, Date firstTime,long period)

This method can be used for scheduling the specified task repeatedly for execution beginning at the specified time.

o    public void schedule (TimerTask task, long delay,long period)

This method schedules execution of the specified TimerTask repeatedly after a specified amount of delay.

Fixed rate repeated executions

In this type of scheduling the tasks are scheduled to run at regular intervals of time. If one execution is delayed then the other executions will occur rapidly thus ensuring that in the longer run the frequency of the executions is the reciprocal of the specified period.

o    public void scheduleAtFixedRate (TimerTask task, Date firstTime, long period)

This method can be used for scheduling the specified task repeatedly for execution beginning at the specified time.

o    public void scheduleAtFixedRate (TimerTask task, long delay, long period)

This method schedules execution of the specified TimerTask repeatedly after a specified amount of delay.

 

TimerTask

 

This class represents the task which has to be scheduled by the Timer. The TimerTask is an abstract class and implements the ‘Runnable’ interface and thus contains the run () method. The actions which should be performed in the executions of the Timer should be implemented in run () method. We will now see an extensive practical example of using the Timer and TimerTask class.

 

 

 

Example Code: Timer & TimerTask

This example shows how to work with Timer and TimerTask. This application display’s a stopwatch. The main feature of this application is that we can store upto 32 different split second timings in an array and display it on canvas. Please remember that the MIDP timer should not be used for timing events that require absolute precesion like track and field events.

 

The following keys are used in our stopwatch:

 

Ø  ‘*’ button

It is used to start and stop the stopwatch.

Ø  ‘0’ button

It is used to set the stopwatch to zero.

Ø  ‘#’ button

It is used to activate the split second functionality.

 

/*************************/
/*             TimerMIDlet.java                     */
/*************************/

import javax.microedition.midlet.*;

import javax.microedition.lcdui.*;

 

/**

 * @author SKJ

 * @version 1.0.0

 */

 

public class TimerMIDlet extends javax.microedition.midlet.MIDlet

{

    private Display display;

 

    //defineing object variable

    private TimerCan can;

   

    public void startApp()    

    {

        this.display = Display.getDisplay(this) ;

        this.can = new TimerCan() ;

 

        //setting current display

        this.display.setCurrent(this.can) ;

    }

   

    public void pauseApp() {

    }

   

    public void destroyApp(boolean unconditional) {

    }

}

 

/*************************/
/*             TimerCanvas.java                   */
/*************************/

import javax.microedition.lcdui.* ;

import java.util.* ;

 

/**

 * @author SKJ

 * @version 1.0.0

 */

 

public class TimerCan extends Canvas

{

    // for Timer

    private Timer timer  ;

   

    // variable to store time

    private int hour[]  ;

    private int sec[]  ;

    private int min[]  ;

    private int msec[]  ;

   

    // Canvas variables

    private int maxX  ;

    private int maxY  ;

   

    //array incement and decrement

    private int current  ;

   

    //g.DrawString variable to display in next line

    private int ctrY  ;   

 

    //store font lenght to display in center of canvas

    private int length  ;

         

    private int offsetY ; 

   

    //time variable

    private String time ;

   

    //font hight and width

    private int strWid ;

    private int strht ;   

   

    private boolean scroll  ;

    private int countpl  ;

    private int rect  ;

   

    //Array increment and decrement variable

    private int counter  ;

   

    //for start and stop of time

    private boolean start  ;

    private boolean stop  ;

   

    private boolean yes  ;

   

    //constructor

    public TimerCan()

    {

        super()  ;

        try

        {

            //getting heigth and width of canvas

            this.maxX = this.getWidth()  ;

            this.maxY = this.getHeight()  ;      

 

            //initilizing variable

            this.ctrY = 0  ;

            this.rect = 0  ;

            this.countpl = 0  ;          

            this.current = 0  ;

            this.offsetY = 0  ;

 

            //Initializing array with Size 33

            this.hour = new int[33]  ;

            this.min = new int[33]  ;

            this.sec = new int[33]  ;

            this.msec = new int[33]  ;

            this.start = false  ;

            this.stop = true  ;

            this.yes = true  ;

            this.scroll = false  ; 

           

            //initilizing array to zero

            for(int j = 0  ; j <= 31 ; j++)

            {

                this.hour[j] = 0  ;

                this.min[j] = 0  ;

                this.sec[j] = 0  ;

                this.msec[j] = 0  ;

            }

        }

       

        catch(Exception e)

        {

            e.printStackTrace()  ;

        }

    }

   

    public void paint(Graphics g)

    {       

        g.setColor(180,254,243) ;

        //draw rectangle

        g.fillRect(0,0,maxX,maxY) ;

       

        //initializing Font       

        Font font = Font.getDefaultFont()  ;

 

        //getting width of string               

        this.strWid =  font.stringWidth("this.time") ;

 

        //getting hieght of string

        this.strht = font.getHeight() ;           

        this.ctrY = this.strht ;

       

        for(int j=1  ; j <= current  ; j++)

        {

            //setting time variable  like 00:00:00:00

            if(hour[j-1] < 10)

            {

                this.time = "0" + String.valueOf(this.hour[j-1]) + ":"; 

            }

            else

            {

                   this.time = String.valueOf(this.hour[j-1]) + ":"  ;

            }

            

            if(min[j-1] < 10)

            {

                this.time = this.time+ "0"+String.valueOf(this.min[j-

                1]) + ":"  ;

            }

            else

            {

                this.time = this.time+ String.valueOf(this.min[j-1]) + 

                ":"  ;

            }

           

            if(sec[j-1] < 10)

            {

                this.time = this.time+"0"+String.valueOf(this.sec[j-1])

               + ":"  ;

            }

            else

            {

                this.time = this.time+String.valueOf(this.sec[j-1]) +

                ":"  ;

            }

           

            if(msec[j-1] < 10)

            {

                this.time = this.time +

                "0"+String.valueOf(this.msec[j1]) ;

            }

            else

            {

                this.time = this.time + String.valueOf(this.msec[j-1]):

            }

           

            this.time = j + ". " + this.time ;                                   

 

            //Getting width of string

            this.strWid =  font.stringWidth(this.time) ;         

            this.length =  this.maxX - this.strWid ;

           

            //Length divided by two for cenrte

            this.length /=2 ;                       

 

            //Setting Color and display stored time

            g.setColor(255,0,128) ;           

            g.drawString(this.time,this.length,this.ctrY-

            this.offsetY,Graphics.TOP|Graphics.LEFT) ;                        

 

            //Increment ctrY by gieght of string to draw time in next

            //line

            this.ctrY +=  this.strht ;

           

        }

               

            // Set time variable like 00:00:00:00

            if(hour[current] < 10)

            {

                this.time = "0" +

                String.valueOf(this.hour[current])+":"  ;

            }

            else

            {

                this.time = String.valueOf(this.hour[current]) + ":" ;  

            }

       

            if(min[current] < 10)

            {

                this.time = this.time +

                "0"+String.valueOf(this.min[current]) + ":"  ;

            }

            else

            {

                this.time = this.time +

                String.valueOf(this.min[current]) + ":"  ;

            }

       

            if(sec[current] < 10)

            {

                this.time = this.time +

                "0"+String.valueOf(this.sec[current]) + ":"  ;

            }

            else

            {

                this.time = this.time +

                String.valueOf(this.sec[current]) + ":"  ;

            }

       

            if(msec[current] < 10)

            {

                this.time = this.time +

                "0"+String.valueOf(this.msec[current]) ;

            }

            else

            {

                this.time = this.time +

                String.valueOf(this.msec[current]) ;

            }  

       

        //Getting width of string

        this.strWid =  font.stringWidth(this.time) ;

        this.length =  this.maxX - this.strWid ;

       

        //Length divided by two for  display in center

        this.length /= 2 ;           

   

        //Setting Color to rect

        g.setColor(255,255,255) ;

       

        //Fillrect to background of running watch                         

        g.fillRect(0,0,maxX,strht) ;       

        g.fillRect(0,(countpl + 1)*strht,maxX,maxY) ;

       

        //Display  time hour:min:sec:msec       

        g.setColor(0,0,0) ;                                               

        g.drawString(this.time,length,0,Graphics.TOP|Graphics.LEFT) ;                                      

       

    }

 

    private void startTimer()

    {

        TimerTask task = new TimerTask()

        {

            public void run()

            {

               msec[current]++ ;

              

                if(msec[current] == 100)

                {

                    msec[current] = 0 ;

                 

                    //sec increment by 1 when msec equal to 100

                    sec[current]++ ;

                }

                else if(sec[current] ==60)

                {

                    sec[current] = 0 ;

                 

                    //min increment by 1 when sec equal to 60

                    min[current]++ ;

                }

                else if(min[current] == 60)

                {

                    min[current] = 0 ;

                       

                    //hour increment by 1 when min equal to 60

                    hour[current]++ ;

                                    }

                else if(hour[current] == 24)

                {

                    hour[current] = 0 ;

                }                                 

                       repaint() ;                 

            } 

        } ;  

        

        timer = new Timer() ;

        timer.scheduleAtFixedRate(task,10,10) ;           

       

    } 

   

    /**

     * Called when a key is pressed.

     */

   

    protected  void keyPressed(int keyCode)

    {

        int action = getGameAction(keyCode) ;

               

        if(action == Canvas.UP && offsetY >0 )

        {  

               offsetY -= strht ;                       

        }

       

        if(action == Canvas.DOWN && offsetY < counter * strht && scroll

        == true)

        {    

               offsetY += strht ;           

        }

       

        if(keyCode == Canvas.KEY_STAR)

        {

            if(this.start == false)

            {

                this.start = true ;

                this.stop = false ;

            }

            else if(this.stop == false)

            {

                this.start = false ;

                this.stop = true ;

                this.timer.cancel() ;

            }

            if(start == true)

            {

                 this.StartTimer() ;

            }

        }

       

        if(keyCode == Canvas.KEY_NUM0)

        {                 

            // Cancellling the Timer effect

            this.timer.cancel() ;

           

            //setting array to zero

            this.hour[current] =0 ;

            this.min[current] =0 ;

            this.sec[current] =0 ;

            this.msec[current] =0 ;       

            this.start = false ;

        }

       

        if(keyCode == Canvas.KEY_POUND)       

        {

            if(start != false)

            {

                if(((maxY - ctrY ) < strht || ctrY >= maxY) && offsetY

                < ((32-countpl) * strht) && current < 32)

                {

                     offsetY += this.strht ;

                     this.scroll = true ;

                     this.counter++ ;

                     this.yes = false ;

                }

                else if(yes)

                {

                    this.countpl++ ;

                    this.rect += this.ctrY ;

                }

                if(current <= 31)

                {

                    this.current++ ;

                    //store current time in array when pound key

                    pressed

                    this.hour[current] =  this.hour[current-1] ;

                    this.min[current] = this.min[current-1] ;

                    this.sec[current] = this.sec[current-1] ;

                    this.msec[current] = this.msec[current-1] ;               

                }

            }

        }

     }

When you launch application following screen is displayed:

 

When you press ‘*’ button then start timer

 

When you press ‘#’ button then display time when you click:

 

 

Comments