Java/J2ME/Animation

Материал из Java эксперт
Перейти к: навигация, поиск

A MIDlet that displays the Doggy animation.

   <source lang="java">

/*

* Copyright (c) 2000-2001 Sun Microsystems, Inc. All Rights Reserved.
*/

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; /**

* A MIDlet that displays the Doggy animation.
*
* @author Mark A. Patel - Motorola, Inc.
* @author Roger Riggs - Sun Microsystems, Inc.
**/

public class DoggyMIDlet extends MIDlet implements CommandListener {

   Command cmdExit;
   /**
    * Constructs a new DoggyMIDlet
    **/
   public DoggyMIDlet() {
       cmdExit = new Command("Exit", Command.EXIT, 1);
   }
   
   /**
    * Starts the app by creating a new Doggy instance and displaying it
    **/
   protected void startApp() throws MIDletStateChangeException {
       Doggy d;
       d = new Doggy();
       d.addCommand(cmdExit);
       d.setCommandListener(this);
       
       Display.getDisplay(this).setCurrent(d);
 
   }
   
   protected void pauseApp() {
   }
   
   protected void destroyApp(boolean unconditional)
 throws MIDletStateChangeException {
   }
   
   public void commandAction(Command c, Displayable d) {
       if (c == cmdExit) {
           try {
               destroyApp(false);
           } catch (Exception e) {}
           notifyDestroyed();
       }
   }

}

class Doggy extends Canvas implements Runnable {
 /**
  * Number of frames in the animation
  **/
 static final int FRAME_COUNT = 17;
 /**
  * Normal frame delay (milliseconds)
  **/
 static final int FRAME_DELAY = 180;
 /**
  * Frame delay for the last frame where the dog is sleeping
  **/
 static final int LAST_FRAME_DELAY = 3000;
 /**
  * Relative horizontal position where each of the frames 
  * should be rendered. 0 represents the left edge of the screen
  * and 1024 represents the right edge of the run distance 
  * (1024 is used so that scaling can be performed using
  * simple bit shifts instead of division operations). 
  **/
 static final int[] framePositions = {
   0, 50, 186, 372, 558, 744, 930, 1024, 1024,
   834, 651, 465, 279, 93, 0, 0, 0
 };
 /**
  * An Image containing the 17 frames of the dog running,
  * stacked vertically.
  * Using a single image is much more efficient than using several 
  * images with each containing a single frame.
  * Each frame can be rendered seperately by setting the clip 
  * region to the size of a single frame and then
  * rendering the image at the correct position so that the desired 
  * frame isaligned with the clip region.
  **/
 Image doggyImages = null;
 /**
  * Width of a single animation frame
  **/
 int frameWidth = 0;
 /**
  * Height of a single animation frame
  **/
 int frameHeight = 0;
 /**
  * Index of the current frame
  **/
 int frameIndex = 0;
 /**
  * The distance, in pixels, that the dog can run (screen width less
  * the width of a single frame)
  **/
 int runLength = 0;
 /**
  * Indicates if the animation is currently running
  **/
 boolean running = false;
 /**
  * Called when this Canvas is shown.  This method starts the timer 
  * that runs the animation sequence.
  **/
 protected void showNotify() {
   if (doggyImages == null) {
     try {
       doggyImages =
         Image.createImage("/examples/animation/Doggy.png");
       frameWidth = doggyImages.getWidth();
       frameHeight = doggyImages.getHeight() / FRAME_COUNT;
     } catch (Exception ioe) {
       return; // no image to animate
     }
   }
   runLength = getWidth() - frameWidth;
   running = true;
   frameIndex = 0;
   new Thread(this).start();
 }
 /**
  * Called when this Canvas is hidden.  This method stops the
  * animation timer to free up processing
  * power while this Canvas is not showing.
  **/
 protected void hideNotify() {
   running = false;
 }
 public void run() {
   // Need to catch InterruptedExceptions and bail if one occurs
   try {
     while (running) {
       Thread.sleep((frameIndex == FRAME_COUNT - 1) ?
              LAST_FRAME_DELAY : FRAME_DELAY);
       // Remember the last frame index so we can compute
       // the repaint region
       int lastFrameIndex = frameIndex;
       // Update the frame index
       frameIndex = (frameIndex + 1) % FRAME_COUNT;
       // Determine the left edge of the repaint region
       int repaintLeft = framePositions[lastFrameIndex];
       int repaintRight = framePositions[frameIndex];
       if (framePositions[lastFrameIndex] > framePositions[frameIndex]) {
         repaintLeft = framePositions[frameIndex];
         repaintRight = framePositions[lastFrameIndex];
       }
       // Scale the repaint coordinates to the width of the screen
       repaintLeft = (repaintLeft * runLength) >> 10;
       repaintRight = (repaintRight * runLength) >> 10;
       // Trigger a repaint of the affected portion of the screen
       // Repaint the region where the last frame was rendered
       // (ensures that it is cleared)
       repaint(repaintLeft, 0,
           frameWidth + repaintRight - repaintLeft, frameHeight);
     }
   } catch (InterruptedException e) {}
 }
 public void paint(Graphics g) {
   // Clear the background (fill with white)     
   // The clip region will limit the area that
   // actually gets cleared to save time
   g.setColor(0xFFFFFF);
   g.fillRect(0, 0, getWidth(), getHeight());
   // Translate the graphics to the appropriate
   // position for the current frame
   g.translate((framePositions[frameIndex] * runLength) >> 10, 0);
   // Constrain the clip region to the size of a single frame
   g.clipRect(0, 0, frameWidth, frameHeight);
   // Draw the current frame by drawing the entire image with
   // the appropriate vertical offset so that the desired frame
   // lines up with the clip region.
   g.drawImage(doggyImages, 0, -(frameIndex * frameHeight),
         Graphics.LEFT + Graphics.TOP);
 }

}


      </source>
   
  
 
  



Animated Timer

   <source lang="java">

/*--------------------------------------------------

* AnimatedTimer - Main midlet.
* Shows canvas with an animated timer. Includes
* configuration options to start/stop the timer
* and to adjust the sleep interval of the thread
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose 
*-------------------------------------------------*/

import java.util.Stack; import javax.microedition.lcdui.Alert; import javax.microedition.lcdui.Canvas; import javax.microedition.lcdui.rumand; import javax.microedition.lcdui.rumandListener; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; import javax.microedition.lcdui.Gauge; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Image; import javax.microedition.lcdui.List; import javax.microedition.midlet.MIDlet; public class AnimatedTimer extends MIDlet {

 private Display display; // The display
 protected TimerCanvas cvTimer; // Canvas to display timer
 protected OptionsList lsOptions; // List to change timer options
 protected SleepForm fmSleep; // Form with gauge to set timer sleep
 protected DisplayManager displayMgr; // Class to help manage screens
 public AnimatedTimer() {
   display = Display.getDisplay(this);
   cvTimer = new TimerCanvas(this);
   lsOptions = new OptionsList("Timer options", List.IMPLICIT, this);
   fmSleep = new SleepForm("Adjust sleep", this);
   // Create a display manager object
   displayMgr = new DisplayManager(display, cvTimer);
 }
 protected void startApp() {
   // Start with the canvas
   display.setCurrent(cvTimer);
 }
 protected void pauseApp() {
 }
 protected void destroyApp(boolean unconditional) {
 }
 public void exitMIDlet() {
   destroyApp(true);
   notifyDestroyed();
 }

} /*--------------------------------------------------

* Use a stack to push and pop displayable objects
*
* public void pushDisplayable(Displayable)
* public void popDisplayable()
* public void home()  
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose 
*-------------------------------------------------*/

class DisplayManager extends Stack {

 private Display display; // Reference to Display object
 private Displayable mainDisplayable; // Main displayable for MIDlet
 private Alert alStackError; // Alert for error conditions
 /*--------------------------------------------------
  * Display manager constructor
  *-------------------------------------------------*/
 public DisplayManager(Display display, Displayable mainDisplayable) {
   // Only one display object per midlet, this is it
   this.display = display;
   this.mainDisplayable = mainDisplayable;
   // Create an alert displayed when an error occurs
   alStackError = new Alert("Displayable Stack Error");
   alStackError.setTimeout(Alert.FOREVER); // Modal
 }
 /*--------------------------------------------------
  * Push the current displayable onto stack and set
  * the passed in displayable as active
  *-------------------------------------------------*/
 public void pushDisplayable(Displayable newDisplayable) {
   push(display.getCurrent());
   display.setCurrent(newDisplayable);
 }
 /*--------------------------------------------------
  * Return to the main displayable object of MIDlet
  *-------------------------------------------------*/
 public void home() {
   while (elementCount > 1)
     pop();
   display.setCurrent(mainDisplayable);
 }
 /*--------------------------------------------------
  * Pop displayable from stack and set as active
  *-------------------------------------------------*/
 public void popDisplayable() {
   // If the stack is not empty, pop next displayable
   if (empty() == false)
     display.setCurrent((Displayable) pop());
   else
     // On error show an alert
     // Once acknowledged, set "mainDisplayable" as active
     display.setCurrent(alStackError, mainDisplayable);
 }

} /*--------------------------------------------------

* Class TimerCanvas
*
* Animate a sequence of images to simulate 
* a moving timer
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose 
*-------------------------------------------------*/

class TimerCanvas extends Canvas implements Runnable, CommandListener {

 private AnimatedTimer midlet; // Main midlet
 private Command cmExit; // Exit midlet
 private Command cmOptions; // Display options list
 private Image im = null; // Sequence of images
 private int imageCount = 4; // Four images in the sequence
 private int imageWidth; // Width of one image in the sequence
 private int imageHeight; // Height of one image in the sequence
 private int imageIndex; // Current image in the sequence
 private int translate_x; // Translated x and y
 private int translate_y;
 private int viewport_x; // Location of the viewport
 private int viewport_y;
 private boolean active = false; // Timer active?
 private boolean requestedToStop = false; // Did user request to stop timer
 private int sleepTime = 400; // Current sleep time (milliseconds)
 public TimerCanvas(AnimatedTimer midlet) {
   // Call canvas constructor
   super();
   // Save reference to MIDlet so we can
   // access the display manager class
   this.midlet = midlet;
   // Create commands & listen for events
   cmExit = new Command("Exit", Command.EXIT, 1);
   cmOptions = new Command("Config", Command.SCREEN, 2);
   addCommand(cmExit);
   addCommand(cmOptions);
   setCommandListener(this);
 }
 /*--------------------------------------------------
  * Application manager is about to display canvas
  *-------------------------------------------------*/
 protected void showNotify() {
   if (im == null) {
     try {
       // Read the png from a file and get width and
       // height of one image in the sequence
       im = Image.createImage("/timer.png");
       imageHeight = im.getHeight();
       imageWidth = im.getWidth() / imageCount;
       // Get the coordinates for x/y of viewport
       // Viewport is centered on the display
       viewport_x = (getWidth() / 2) - (imageWidth / 2);
       viewport_y = (getHeight() / 2) - (imageHeight / 2);
       // Set first translated coordinate to match viewport
       translate_x = viewport_x;
       translate_y = viewport_y;
     } catch (Exception e) {
       System.err.println("Unable to read png file.");
     }
     // Begin with the first image in the sequence
     imageIndex = 0;
   }
   // If the user has not requested to stop the timer...
   if (!requestedToStop)
     active = true;
   new Thread(this).start();
 }
 /*--------------------------------------------------
  * Application manager is no longer displaying canvas
  *-------------------------------------------------*/
 protected void hideNotify() {
   active = false;
 }
 /*--------------------------------------------------
  * Draw next timer in sequence
  *-------------------------------------------------*/
 protected void paint(Graphics g) {
   if (im != null) {
     // Due to a bug in MIDP 1.0.3 we need to
     // force a clear of the display
     g.setColor(255, 255, 255); // White pen
     g.fillRect(0, 0, getWidth(), getHeight());
     g.setColor(0, 0, 0); // Black pen
     // Viewport at center of display
     g.setClip(viewport_x, viewport_y, imageWidth, imageHeight);
     // Draw image at translated coordinates
     g.drawImage(im, translate_x, translate_y, Graphics.TOP
         | Graphics.LEFT);
   }
 }
 /*--------------------------------------------------
  * Loop forever, translating image coordinates
  *-------------------------------------------------*/
 public void run() {
   try {
     while (active) {
       Thread.sleep(sleepTime);
       repaint();
       // Reached the last image in sequence
       if (imageIndex == imageCount - 1) {
         // Reset translated coordinates
         translate_x = viewport_x;
         translate_y = viewport_y;
       } else {
         // Translate coordinate system to the left
         translate_x -= imageWidth;
       }
       // Which image in the sequence is next
       imageIndex = (imageIndex + 1) % imageCount;
     }
   } catch (InterruptedException e) {
   }
 }
 /*--------------------------------------------------
  * Called from the "Config" options menu
  *-------------------------------------------------*/
 public void startTimer() {
   requestedToStop = false;
   active = true;
   repaint();
 }
 /*--------------------------------------------------
  * Called from the "Config" options menu
  *-------------------------------------------------*/
 public void stopTimer() {
   requestedToStop = true;
   active = false;
   repaint();
 }
 /*--------------------------------------------------
  * Called from form/gauge to adjust sleep
  *-------------------------------------------------*/
 public void setSleep(int sleepTime) {
   this.sleepTime = sleepTime;
 }
 /*--------------------------------------------------
  * Called from form/gauge to adjust sleep
  *-------------------------------------------------*/
 public int getSleep() {
   return sleepTime;
 }
 /*--------------------------------------------------
  * Command event handling
  *-------------------------------------------------*/
 public void commandAction(Command c, Displayable s) {
   if (c == cmOptions) {
     // Push current displayable and show the options list
     midlet.displayMgr.pushDisplayable(midlet.lsOptions);
   } else if (c == cmExit) {
     midlet.exitMIDlet();
   }
 }

} /*--------------------------------------------------

* Class SleepForm
*
* Form with gauge to adjust sleep interval of timer
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose 
*-------------------------------------------------*/

class SleepForm extends Form implements CommandListener {

 private AnimatedTimer midlet; // Main midlet
 private Command cmBack, // Back to options list
     cmHome, // Go to main displayable (canvas)
     cmSave; // Save new sleep time
 private Gauge gaSleep; // Gauge to adjust sleep
 public SleepForm(String title, AnimatedTimer midlet) {
   // Call the form constructor
   super(title);
   // Save reference to MIDlet so we can
   // access the display manager class
   this.midlet = midlet;
   // Commands
   cmSave = new Command("Save", Command.SCREEN, 1);
   cmBack = new Command("Back", Command.BACK, 2);
   cmHome = new Command("Home", Command.SCREEN, 2);
   // Gauge to adjust the length of timer sleep
   gaSleep = new Gauge("Timer Sleep", true, 100, 1000);
   // Set to current sleep. Gauge holds values 0 to 100,
   // divide the current sleep (milliseconds) by 10
   gaSleep.setValue(midlet.cvTimer.getSleep() / 10);
   // Add to form and listen for events
   append(gaSleep);
   addCommand(cmSave);
   addCommand(cmBack);
   addCommand(cmHome);
   setCommandListener(this);
 }
 /*--------------------------------------------------
  * Command event handling
  *-------------------------------------------------*/
 public void commandAction(Command c, Displayable s) {
   if (c == cmSave) {
     // Gauge returns a value between 0 and 100
     // We want milliseconds, so multiply by 10
     midlet.cvTimer.setSleep(gaSleep.getValue() * 10);
     // Return to main midlet
     midlet.displayMgr.home();
   } else if (c == cmBack) {
     // Pop the last displayable off the stack
     midlet.displayMgr.popDisplayable();
   } else if (c == cmHome) {
     // Return to main midlet
     midlet.displayMgr.home();
   }
 }

} /*--------------------------------------------------

* Class OptionsList
*
* List to provide options for configuring of timer
*
* Example from the book:     Core J2ME Technology
* Copyright John W. Muchow   http://www.CoreJ2ME.ru
* You may use/modify for any non-commercial purpose 
*-------------------------------------------------*/

class OptionsList extends List implements CommandListener {

 private AnimatedTimer midlet; // Main midlet
 private Command cmBack;
 public OptionsList(String title, int listType, AnimatedTimer midlet) {
   // Call list constructor
   super(title, listType);
   // Save reference to MIDlet so we can
   // access the display manager class
   this.midlet = midlet;
   // Create the list entries
   append("Sleep interval", null);
   append("Start", null);
   append("Stop", null);
   // Create command and listen for events
   cmBack = new Command("Back", Command.BACK, 1);
   addCommand(cmBack);
   setCommandListener(this);
 }
 /*--------------------------------------------------
  * Command event handling
  *-------------------------------------------------*/
 public void commandAction(Command c, Displayable s) {
   // Event generated by the implicit list
   if (c == List.SELECT_COMMAND) {
     switch (getSelectedIndex()) {
     case 0:
       // Push current displayable and show the form
       // to adjust the timer sleep
       midlet.displayMgr.pushDisplayable(midlet.fmSleep);
       break;
     case 1:
       // Start timer and return to previous displayable
       midlet.cvTimer.startTimer();
       midlet.displayMgr.popDisplayable();
       break;
     case 2:
       // Stop timer and return to previous displayable
       midlet.cvTimer.stopTimer();
       midlet.displayMgr.popDisplayable();
       break;
     }
   } else if (c == cmBack) {
     // Return to previous displayable
     midlet.displayMgr.popDisplayable();
   }
 }

}


      </source>
   
  
 
  



Animation MIDlet

   <source lang="java">

/* J2ME in a Nutshell By Kim Topley ISBN: 0-596-00253-X

  • /

import java.util.Timer; import java.util.TimerTask; import javax.microedition.lcdui.Canvas; import javax.microedition.lcdui.rumand; import javax.microedition.lcdui.rumandListener; import javax.microedition.lcdui.Display; import javax.microedition.lcdui.Displayable; import javax.microedition.lcdui.Form; import javax.microedition.lcdui.Gauge; import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.Item; import javax.microedition.lcdui.ItemStateListener; import javax.microedition.midlet.MIDlet; public class AnimationMIDlet extends MIDlet

                       implements CommandListener, ItemStateListener {
   // The MIDlet"s Display object
   private Display display;
       
   // Flag indicating first call of startApp
   protected boolean started;
   
   // Exit command
   private Command exitCommand;
   
   // Setup command
   private Command setupCommand;
   
   // Run command
   private Command runCommand;
   
   // Configuration form
   private Form form;
   
   // Animation canvas
   private AnimationCanvas canvas;
   
   // Gauge for block count
   private Gauge blockGauge;
   
   // Gauge for frame rate
   private Gauge rateGauge;
   
   // Initial frame rate
   private static final int FRAME_RATE = 1;
   
   // Initial number of blocks
   private static final int BLOCK_COUNT = 1;
   
   protected void startApp() {
       if (!started) {
           display = Display.getDisplay(this);
           form = new Form("Animation");
           rateGauge = new Gauge("Frame rate", true, 10, FRAME_RATE);
           blockGauge = new Gauge("Blocks", true, 4, BLOCK_COUNT);
           form.append(rateGauge);
           form.append(blockGauge);
           form.setItemStateListener(this);
           
           canvas = createAnimationCanvas();            
           
           exitCommand = new Command("Exit", Command.EXIT, 0);
           setupCommand = new Command("Setup", Command.SCREEN, 0);
           runCommand = new Command("Run", Command.SCREEN, 0);
           
           canvas.addCommand(exitCommand);
           canvas.addCommand(setupCommand);
           form.addCommand(exitCommand);
           form.addCommand(runCommand);
           
           form.setCommandListener(this);
           canvas.setCommandListener(this);
           
           display.setCurrent(form);
           started = true;
       }
   }
   protected void pauseApp() {
   }
   protected void destroyApp(boolean unconditional) {
   }    
   public void commandAction(Command c, Displayable d) {
       if (c == exitCommand) {
           // Exit. No need to call destroyApp
           // because it is empty.
           notifyDestroyed();
       } else if (c == runCommand) {
           display.setCurrent(canvas);
       } else if (c == setupCommand) {
           display.setCurrent(form);
       }
   }
   
   public void itemStateChanged(Item item) {
       if (item == blockGauge) {
           int count = blockGauge.getValue();
           if (count < 1) {
               count = 1;
           }
           canvas.setBlockCount(count);
       } else if (item == rateGauge) {
           int count = rateGauge.getValue();
           if (count < 1) {
               count = 1;
           }
           canvas.setFrameRate(count);
       }            
   } 
   
   // Creates the canvas that will draw the block
   protected AnimationCanvas createAnimationCanvas() {
       return new AnimationCanvas();
   }
   
   class AnimationCanvas extends Canvas {
       // Size of each block
       protected static final int SIZE = 4;
       
       // Initial speeds in the X direction
       protected final int[] xSpeeds = { 2, -2, 0, -2 };
       
       // Initial speeds in the Y direction
       protected final int[] ySpeeds = { 2, -2, 2, -0 };
       
       // Background color
       protected int background = display.isColor() ? 0 : 0xc0c0c0;
           
       // Foreground color
       protected int foreground = display.isColor() ? 0xffff00 : 0;
       
       // Width of screen
       protected int width = getWidth();
       
       // Height of screen
       protected int height = getHeight();
       
       // The screen update rate
       protected int frameRate;
       
       // The blocks to draw on the screen
       protected Block[] blocks;
       
       // The update timer
       protected Timer timer;
       
       // The update timer task
       protected TimerTask updateTask;
       
       // Gets the maximum number of blocks
       public int getMaxBlocks() {
           return blocks.length;
       }
       
       // Constructs a canvas with default settings
       AnimationCanvas() {
           setBlockCount(BLOCK_COUNT);
           setFrameRate(FRAME_RATE);
       }
       
       // Sets the number of blocks to draw
       public void setBlockCount(int count) {
           if (count > xSpeeds.length) {
               throw new IllegalArgumentException("Cannot have more than " 
                               + xSpeeds.length + " blocks");
           }
           
           blocks = new Block[count];
           createBlocks();
       }
       
       // Gets the number of blocks to draw
       public int getBlockCount() {
           return blocks.length;
       }
       
       // Sets the number of updates per second
       public void setFrameRate(int frameRate) {
           if (frameRate < 1 || frameRate > 10) {
               throw new IllegalArgumentException("Frame rate must be > 0 and <= 10");
           }
           this.frameRate = frameRate;
           if (isShown()) {
               startFrameTimer();
           }
       }
       
       // Gets the number of updates per second
       public int getFrameRate() {
           return frameRate;
       }  
         
       // Paint canvas background and all
       // of the blocks in their correct locations.
       protected void paint(Graphics g) {
           // Paint with the background color
           g.setColor(background);
           g.fillRect(0, 0, width, height);
           
           // Draw all of the blocks
           g.setColor(foreground);
           synchronized (this) {
               for (int i = 0, count = blocks.length; i < count; i++) {
                   g.fillRect(blocks[i].x, blocks[i].y, SIZE, SIZE);
               }
           }
       }
       
       // Notification that the canvas has been made visible
       protected void showNotify() {
           // Start the frame timer running
           startFrameTimer();
       }
       
       // Notification that the canvas is no longer visible
       protected void hideNotify() {
           // Stop the frame timer 
           stopFrameTimer();
       }
       
       // Creates the blocks to be displayed
       private void createBlocks() {
           int startX = (width - SIZE)/2;
           int startY = (height - SIZE)/2;
           for (int i = 0, count = blocks.length; i < count; i++) {
               blocks[i] = new Block(startX, startY, xSpeeds[i], ySpeeds[i]);
           }
       }
       
       // Starts the frame redraw timer
       protected void startFrameTimer() {
           timer = new Timer();
           
           updateTask = new TimerTask() {
               public void run() {
                   moveAllBlocks();
               }
           };
           long interval = 1000/frameRate;
           timer.schedule(updateTask, interval, interval);
       }
       
       // Stops the frame redraw timer
       protected void stopFrameTimer() {
           timer.cancel();            
       }
       
       // Called on expiry of timer.
       public synchronized void moveAllBlocks() {
           // Update the positions and speeds
           // of all of the blocks
           for (int i = 0, count = blocks.length; i < count; i++) {
               blocks[i].move();
               
               // Request a repaint of the screen
               repaint();                
           }
       }
       
       // Inner class used to represent a block on the screen
       class Block {
           int x;      // X position
           int y;      // Y position
           int xSpeed; // Speed in the X direction
           int ySpeed; // Speed in the Y direction
           
           Block(int x, int y, int xSpeed, int ySpeed) {
               this.x = x;
               this.y = y;
               this.xSpeed = xSpeed;
               this.ySpeed = ySpeed;
           }
           
           void move() {
               x += xSpeed;
               if (x <= 0 || x + SIZE >= width) {
                   xSpeed = -xSpeed;
               }
               
               y += ySpeed;
               if (y <= 0 || y + SIZE >= height) {
                   ySpeed = -ySpeed;
               }                
           }            
       }
   }

}


      </source>
   
  
 
  



Animation MIDlet 2

   <source lang="java">

/* J2ME in a Nutshell By Kim Topley ISBN: 0-596-00253-X

  • /

import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class AnimationMIDlet2 extends AnimationMIDlet {

   // Create an AnimationCanvas2
   protected AnimationMIDlet.AnimationCanvas createAnimationCanvas() {
       return new AnimationCanvas2();
   }
   
   class AnimationCanvas2 extends AnimationMIDlet.AnimationCanvas {
       // Override superclass paint method to take
       // into account the clipping rectangle
       protected void paint(Graphics g) {
           // Get the clipping rectange
           int clipX = g.getClipX();
           int clipY = g.getClipY();
           int clipWidth = g.getClipWidth();
           int clipHeight = g.getClipHeight();
           
           // Paint with the background color - only
           // the area within the clipping rectangle
           g.setColor(background);
           g.fillRect(clipX, clipY, clipWidth, clipHeight);
           
           // Draw all of the blocks
           g.setColor(foreground);
           synchronized (this) {
               for (int i = 0, count = blocks.length; i < count; i++) {
                   g.fillRect(blocks[i].x, blocks[i].y, SIZE, SIZE);
               }
           }
       }       
               
       // Called on expiry of timer.
       public synchronized void moveAllBlocks() {
           // Update the positions and speeds
           // of all of the blocks and repaint
           // only the part of the screen that
           // they occupy
           for (int i = 0, count = blocks.length; i < count; i++) {
               // Request a repaint of the current location
               Block block = blocks[i];
               repaint(block.x, block.y, SIZE, SIZE);
               
               blocks[i].move();
               
               // Request a repaint of the new location
               repaint(block.x, block.y, SIZE, SIZE);
           }
       }
   }

}


      </source>