/************************************** * Source & Further Reading: J. W. Muchow (2002), Core J2ME Technology & MIDP, Sun MICROSYSTEMS ***************************************/ // Animate a moving image to simulate the timer import javax.microedition.lcdui.*; public class TimerCanvas extends Canvas implements Runnable, CommandListener{ private AnimTimer midlet; // main midlet private Command cmExit; // exit command private Command cmOptions; // display options command private Image im=null; // sequence of images private int imageCnt = 4; // four images for the squence private int imageWidth; // width of the image sequence private int imageHeight; // image sequence height private int imageIndex; // current image private int transImage_x, transImage_y ; //Translated x & y coordinates private int viewPort_x, viewPort_y; // location of the view port private int sleepTime = 450; // current sleep time private boolean active = false; // timer active private boolean Stoprequest = false; // request to stop timer // constructor public TimerCanvas(AnimTimer midlet){ // call canvas constructor super(); // save reference to midlet to access the DisplayManager this.midlet = midlet; // create commands and listen for events cmExit = new Command("Exit", Command.EXIT, 1); cmOptions = new Command("Options:", Command.SCREEN, 1); addCommand(cmExit); addCommand(cmOptions); setCommandListener(this); } // Application manager to display canvas protected void showNotify(){ if(im == null){ try{ // Read the image file and get width & height im = Image.createImage("/sand.png"); imageHeight = im.getHeight(); imageWidth = im.getWidth()/imageCnt; // get the coordinates for x & y of viewport // put the viweport at the centre of display viewPort_x = (getWidth() / 2) - (imageWidth / 2); viewPort_y = (getHeight() / 2) - (imageHeight / 2); // set the first translated coordinate to match viewport transImage_x = viewPort_x; transImage_y = viewPort_y; } catch (Exception e){ System.err.println("Unable to detect sand.png"); } // start with the first image in the sequence imageIndex = 0; } // check if user has not stopped the timer if so keep timer active if(!Stoprequest) active = true; new Thread(this).start(); } // Application manager is not displaying canvas protected void hideNotify(){ active = false; } // Draw next timer in sequence protected void paint (Graphics g){ if(im !=null){ // Viewport to be put at centre of dicplay g.setClip(viewPort_x, viewPort_y, imageWidth, imageHeight); // Draw image at translated coordinates g.drawImage(im, transImage_x, transImage_y, Graphics.TOP | Graphics.LEFT); } } // Loop and translate coordinates public void run(){ try{ while(active){ Thread.sleep(sleepTime); repaint(); // Reached the last sequence in image if(imageIndex == imageCnt -1){ // rest translate coordinate transImage_x = viewPort_x; transImage_y = viewPort_y; } else{ // translate coordinate system to the left transImage_x -=imageWidth; } // check wich image is next in the sequence imageIndex = (imageIndex + 1) % imageCnt; } } catch(InterruptedException e){ } } // call from Options menu public void startTimer(){ Stoprequest = false; active = true; repaint(); } public void stopTimer(){ Stoprequest = true; active = false; repaint(); } // call from Form/gauge to adjust sleep public void setSleep(int sleepTime){ this.sleepTime = sleepTime; } public int getSleep(){ return sleepTime; } // command for event handling public void commandAction(Command c, Displayable d){ if(c == cmOptions){ // push diplayable and show the options midlet.displayMgr.pushDisplayable(midlet.lsOpt); } else if (c == cmExit){ midlet.exitMIDlet(); } } }