Simple Animation of Objects - Update Only

Previous      Next      Applet      Java 1.2 Applet Source

// Differences with the previous code are in red.
// This code does not use double buffering and only update.
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;

class Dot implements Runnable
{
   Thread runner;
   float left;    // current pixels in from left
   float top;     // current pixels in from top
   float x;       // destination pixels in from left
   float y;       // destination pixels in from top
   int number;    // identification of dot
   Color color;   // color of dot
   int dia = 30;  // diameter of dot
   float xdiff=0; // difference between mouse pos and
   float ydiff=0; // top left corner of dot

   public Dot(int n, Color clr, int left, int top)
   {
      number = n;
      color = clr;
      this.left = x = (float)left;
      this.top  = y = (float)top;
      runner = new Thread(this);
      runner.start();
   }

   public boolean over (int x, int y)  // returns true iff mouse is over dot
   {                                   // x and y are mouse coordinates
      if (x > left && left+dia > x && y > top && top+dia > y)
         return true;
      else
         return false;
   }
   void  setPosition(int l, int t)
   {
      top  = (float)t - ydiff;
      left = (float)l - xdiff;
   }

   void  setDiff(int x, int y) { xdiff = x - left; ydiff = y - top; }
   
   public void run ()
   {
      while (true)
      {
         try
         {
            runner.sleep(40);
         }
         catch (InterruptedException e) {  break;  }
         left = ((float)(.99*(left - x) + x));
         top  = ((float)(.99*(top - y) + y));
      }
   }
   
   public void suspend () { runner.suspend(); }
   public void resume ()  { runner.resume(); }   
   
   public void paintDot(Graphics g, FontMetrics fm)
   {
      String lbl = String.valueOf(number);
      int w = fm.stringWidth(lbl);
      int h = fm.getHeight();
      g.setColor(color);
      g.fillOval((int)left, (int)top, dia, dia);
      g.setColor(Color.white);
      g.drawString(lbl, (int)left-w/2+dia/2, (int)top+12+h/2);
   }
}

class Cell
{
   Dot obj;
   Cell next;
   Cell prev;
   
   Cell (Dot obj, Cell next, Cell prev)
   {
      this.obj = obj;
      this.next = next;
      this.prev = prev;
   }
}

class MyObjectList
{
   Cell head = null;
   Cell tail = null;
   
   void add (Dot obj)
   {
      if (head == null)
         head = tail = new Cell(obj, null, null);
      else
      {
         head = new Cell(obj, head, null);
         head.next.prev = head;
      }
   }
   Dot findAndMoveToTop (int x, int y)
   {
      Cell a,b,c;

      if (head == null) return null;
      for (c=head ; c != null ; c=c.next)
      {
         if (c.obj.over(x,y))
         {            
            if (head != c)
            {
               a = c.prev;
               b = c.next;
               a.next = b;
               if (b != null) b.prev = a; else tail = a;
               c.next = head;
               c.prev = null;
               head.prev = c;
               head = c;
            }
            return head.obj;            
         }
      }
      return null;
   }
   void display (Graphics g, FontMetrics f)
   {
      for (Cell cell=tail ; cell != null ; cell = cell.prev)
         cell.obj.paintDot(g,f);
   }
}

public class RB   extends java.applet.Applet
                  implements Runnable, MouseMotionListener
{
   Thread runner;
   Dot pick;
   Color color;
   MyObjectList mol;
   
   MouseAdapter ma = new MouseAdapter()
   {
      public void mousePressed (MouseEvent event)
      {
         pick = mol.findAndMoveToTop(event.getX(),event.getY());
         if (pick != null)
         {
            pick.setDiff(event.getX(),event.getY());
            pick.suspend();
         }
      }
      
      public void mouseReleased (MouseEvent event)
      {
         if (pick == null) return;
         pick.resume();
         pick = null;
      }
   };

   public void init()
   {
      double r = 150;
      double pi = 355.0/113.0;
      double c = 1.0/16.0;
      int x,y;
      mol = new MyObjectList();
      
      for (int i=0 ; i < 8 ; i++, c+=0.125)
      {
         color = Color.getHSBColor((float)c, (float)1.0, (float)1.0);
         x = (int)(r*(Math.sin(c*2*pi)+1.8));
         y = (int)(r*(Math.cos(c*2*pi)+1.35));
         mol.add(new Dot(i+1,color,x,y));
      }

      runner = new Thread(this);
      runner.start();
      addMouseListener(ma);
      addMouseMotionListener(this);
      repaint();
   }

   public void run()
   {
      while (true)
      {
         try
         {
            runner.sleep(100);
         }
         catch (Exception e)   {   }
         repaint();
      }
   }
   
   public void update(Graphics g)
   {
      FontMetrics fm = g.getFontMetrics();
      mol.display(g,fm);
   }

   public void mouseMoved (MouseEvent event) {   }
   
   public void mouseDragged (MouseEvent event) 
   {
      if (pick != null) pick.setPosition(event.getX(),event.getY());
   }
}