runnable & paint relation?

Dear all,

I have a concept question which is related to runnable and paint since I try to make 2D animation. My question is if I have a class which extend Applet/Canvas and implements Runnable, then what is the relation between runnable() & paint() ?

Let me make my question clear, I should use paint() to put a 2D shape on the frame and I should use runnable if I want to move the 2D shape.

- Do I have to use paint() before runnable()?

- Should I consider that runnable is a while loop?

thanks

import java.awt.*;

import java.awt.event.*;

/*###################################################*/

publicclass BoxShootextends Canvasimplements Runnable{

int dY,dX;

Image offScrImg;

Circle ball;

boolean initCanvas=true;

Thread drawThread;

int frameRate;

double deltaT;

double speedUp;

double gPhysical;

double physicalHeight;

/*--*/

//

public BoxShoot(){

setBackground(Color.white);

dY=240;

dX=196;

setSize(dX,dY);

init();

}

/*--*/

//

publicvoid init(){

// Get the drawing area of the applet

// Choose some parameter for the object to drop

int radius = dY/20;

int x0 = 2 * radius;

int y0 = 2 * radius;

// These parameters separate thread animation

// frame rates from the physical time of the

// falling object.

frameRate = 10;

speedUp = 1.0;

deltaT = frameRate/1000.0;

deltaT *= speedUp;

gPhysical = 980.;// = 9.8cm/s**2

physicalHeight = 200.0;

// Scale physical g units to the graphical pixel units

// Let the frame represent a 200cm in height.

double g = gPhysical * ( dY/physicalHeight);

// Create the object to drop

ball =new Circle(x0,y0,radius,dX,dY,g);

// set it's initial velocity

ball.VxInit= 20.0;

ball.VyInit= 0.0;

// Lowest velocity before declaring stopped

ball.Vxstop= 1.00;

ball.Vystop= 1.00;

//

}

/*--*/

publicvoid start(){

if (drawThread !=null){

stop();

}

ball.reset();

initCanvas=true;

drawThread =new Thread(this);

drawThread.start();

}

/*--*/

publicvoid stop(){

drawThread =null;

// Give this thread time to jump out of its loop in run()

try{

Thread.sleep(200);

}catch (InterruptedException e)

{}

}

/*--*/

publicvoid run(){

repaint();

while (drawThread !=null){

// Use sleep to pause between movements

try{

Thread.sleep(frameRate);

}catch (InterruptedException e)

{}

if( ball.xStop && ball.yStop){

stop();

break;

}

ball.move(deltaT);

repaint();

}

System.out.println("Drop finished");

}

/*--*/

publicsynchronizedvoid update( Graphics g ){

// Create an offscreen image and then get its graphics context

if ( offScrImg ==null )

offScrImg = createImage( dX, dY );

Graphics og = offScrImg.getGraphics();

// Now draw on the offscreen image.

paint( og );

// Don't bother to call paint, just draw the offscreen image

// to the screen.

g.drawImage(offScrImg, 0, 0,this);

// Get rid of the offscreen graphics context. Can't unclip a graphics

// context so have to get a new one next time around.

og.dispose();

}

/*--*/

publicsynchronizedvoid paint(Graphics g){

if( initCanvas ){

g.setColor(Color.white);

g.fillRect(0,0,dX,dY);

initCanvas=false;

}

ball.draw(g);

}

}

[7305 byte] By [marco_wua] at [2007-11-27 8:47:29]
# 1

Do I have to use paint() before runnable()?

You set up your graphic component so it can accuratly render its state at any time. Then you

have the animation/Runnable/thread do two things in a loop: advance the animation and then

call repaint on the graphic component. Calling repaint causes the updated state to be drawn.

The state is any/all member variables that can be/are changed to move the animation along.

In the example below the state includes the ball, theta and thetaInc.

Should I consider that runnable is a while loop?

This would be okay for starters. The runnable has a run method that is called by the Thread

that started the Runnable. You can put whatever you want inside the run method. We use a

while loop for animations. So, for animations, yes you can consider that the runnable will

function like a while loop.

Here's a simple example to demonstrate the basics.

import java.awt.*;

import java.awt.geom.Ellipse2D;

import javax.swing.*;

public class BasicAnimation extends JPanel implements Runnable {

Ellipse2D.Double ball = new Ellipse2D.Double(333,183,50,50);

double theta = 0;

double thetaInc = Math.toRadians(1.0);

Thread thread;

boolean running = false;

protected void paintComponent(Graphics g) {

super.paintComponent(g);

Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,

RenderingHints.VALUE_ANTIALIAS_ON);

g2.setPaint(Color.red);

g2.fill(ball);

}

public void run() {

// All the action is inside here.

while(running) {

try {

Thread.sleep(25);

} catch(InterruptedException e) {

System.out.println("interrupted");

stop();

}

// Change the member variable.

theta += thetaInc;

// Update the position of the ball.

moveBall();

// Draw the ball in its new position.

repaint();

}

}

private void moveBall() {

int w = getWidth();

int h = getHeight();

double d = Math.min(w,h)*3/8;

double x = w/2 + d*Math.cos(theta);

double y = h/2 + d*Math.sin(theta);

ball.setFrameFromCenter(x, y, x+ball.width/2, y+ball.height/2);

}

private void start() {

if(!running) {

running = true;

thread = new Thread(this);

thread.setPriority(Thread.NORM_PRIORITY);

thread.start();

}

}

private void stop() {

running = false;

if(thread != null)

thread.interrupt();

thread = null;

}

public static void main(String[] args) {

BasicAnimation test = new BasicAnimation();

JFrame f = new JFrame();

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

f.getContentPane().add(test);

f.setSize(400,400);

f.setLocation(200,200);

f.setVisible(true);

test.start();

}

}

crwooda at 2007-7-12 20:52:25 > top of Java-index,Security,Cryptography...