-
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);
}
}
-
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
Forum Rules
|
Top DevX Stories
Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL
|
Bookmarks