Animation problem


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 2 of 2

Thread: Animation problem

  1. #1
    Join Date
    Nov 2004
    Posts
    7

    Animation problem

    Hi,
    I am writing a simple animation application.It is supposed to countinuosly shows a word on the screen and every 30 ms change the location of the word according to a formula.
    I thought that it had to worked automatically using Thread but after showing the word on the screen for the first time , it do not change the position of the word.Actually I was expected to have from Main() -> Start() -> Run() (updating position and also the screen using repant())if I add ex.start() at the end of the main() everything works but the background do not update.

    import java.awt.*;
    import javax.swing.*;

    public class AnimateEx extends JFrame implements Runnable
    {
    Thread theThread;
    String theString = "Hello Java";
    int x = 120;
    int y = 120;
    int dx = 1;
    int dy = 1;
    final static int STEP = 5;
    final static int MIN = 0;
    int maxX = 0;
    int maxY = 0;
    int stringTop, stringBottom, stringWidth;

    public void start()
    {
    theThread = new Thread(this);
    theThread.start();
    }

    /* public void stop()
    {
    if (theThread != null)
    theThread.stop();
    theThread = null;
    }
    */
    public void run()
    {
    while (true)
    {
    x += dx * STEP;
    if (x < MIN || x + stringWidth > maxX) dx *= -1;
    if (x < MIN ) x = MIN;
    if (x + stringWidth > maxX) x = maxX - stringWidth;

    y += dy * STEP;
    if (y - stringTop < MIN || y + stringBottom > maxY) dy *= -1;
    if (y - stringTop < MIN ) y = MIN + stringTop;
    if (y + stringBottom > maxY) y = maxY - stringBottom;

    repaint();

    try { Thread.sleep(30); }
    catch (InterruptedException interrupted) { /* null action */ }
    }
    }



    public void paint(Graphics g)
    {
    maxX = getSize().width;
    maxY = getSize().height;
    g.drawString(theString, x, y);
    FontMetrics fm= g.getFontMetrics();
    stringWidth = fm.stringWidth(theString);
    stringTop = fm.getAscent();
    stringBottom = fm.getDescent();
    }
    public AnimateEx()
    {
    setSize(770,420);
    setFont( new Font("TimesRoman", Font.BOLD+Font.ITALIC, 24));
    setBackground(Color.yellow);
    setForeground(Color.red);
    }



    public static void main(String[] args){
    AnimateEx ex= new AnimateEx();
    ex.setVisible(true);
    }
    }

  2. #2
    Join Date
    Nov 2004
    Location
    Norway
    Posts
    1,560
    You didn't draw the background, but the result wan't all that bad.

    I have modified your code a bit, and introduced double buffering. A tecnique where you draw on a memory image and copy that image to the displays graphics when the drawing is ready. Not so much a necessity in this case, but with more complicated image updates you may get flickering if you draw on an image while it is being rendered on the display.

    Another thing, the interruption of a thread running in an applet should make the thread to stop. This is because the interruptedexception is thrown when the client leaves the webpage of the applet. If you don't stop the thread it will keep on running uselessly in hte background, and that's not nice.

    Anyway here is my fixup

    Code:
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    import java.awt.image.*;
    
    public class AnimateEx extends JFrame implements Runnable {
      Thread theThread;
      String theString = null;
      int x = 120;
      int y = 120;
      int dx = 1;
      int dy = 1;
      final static int STEP = 2;
      final static int MIN = 0;
      int maxX = 0;
      int maxY = 0;
      BufferedImage memImage=null;
      Graphics2D memG=null;
      int stringTop, stringBottom, stringWidth;
      Font drawFont= new Font("TimesRoman", Font.BOLD+Font.ITALIC, 24);
      FontMetrics fm=null;
      boolean running=false;
      long frequency=30;
      public AnimateEx() {
        setBounds(10,10,770,420);
        memImage = new BufferedImage(770,420, BufferedImage.TYPE_INT_RGB);
        memG = memImage.createGraphics();
        fm= memG.getFontMetrics(drawFont);
        addWindowListener(new WindowAdapter(){
          public void windowClosing(WindowEvent e){
              System.out.println("bye for now");
              stop();
              System.exit(0);
          }});
    
      }
      public void setString(String theString) {
        this.theString=theString;
        stringWidth = fm.stringWidth(theString);
        stringTop = fm.getAscent();
        stringBottom = fm.getDescent();
      }
      public void setFrequency(long frequency) {
        this.frequency=frequency;
      }
      // note: the Thread stop method should never be used
      public synchronized void setRunning(boolean running) {
        this.running=running;
      }
      public synchronized boolean getRunning() {
        return running;
      }
      public void start() {
        theThread = new Thread(this);
        setRunning(true);
        theThread.start();
      }
      public void stop () {
        setRunning (false);
      }
      public void calculateCoords() {
        x += dx * STEP;
        if (x < MIN || x + stringWidth > maxX) dx *= -1;
        if (x < MIN ) x = MIN;
        if (x + stringWidth > maxX) x = maxX - stringWidth;
        y += dy * STEP;
        if (y - stringTop < MIN || y + stringBottom > maxY) dy *= -1;
        if (y - stringTop < MIN ) y = MIN + stringTop;
        if (y + stringBottom > maxY) y = maxY - stringBottom;
      }
      public void run() {
        while (getRunning()) {
          calculateCoords();
          repaint();
          try {
            theThread.sleep(frequency);
          } catch (InterruptedException interrupted) {
            stop();
            return;
          }
        }
      }
      public void update(Graphics g) {
        maxX = getSize().width;
        maxY = getSize().height;
        memG.setColor(Color.yellow);
        memG.fillRect(0,0,maxX, maxY);
        memG.setColor(Color.red);
        memG.setFont(drawFont);
        memG.drawString(theString, x, y);
        g.drawImage(memImage,0,0,this);
      }
      public void paint(Graphics g) {
        update(g);
      }
      public static void main(String[] args) {
         AnimateEx ae=new AnimateEx();
         ae.setString("Hello Java");
         ae.setFrequency(15);
         ae.setVisible(true);
         ae.start();
      }
    }
    eschew obfuscation

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center