Drawing graphs
Hi,
I'm trying to develop an application that would have a graphical output that moves. For example, plotting a sin wave, the wave would move went it comes to 'the end' of the screen.
Can this be done? What are the classes that I need to use, if not are there packages that I could download to have this done?
Thanks.
Desmond
[359 byte] By [
sandrider] at [2007-9-27 19:08:44]

Try this:
Yiu can email fore more help noah.wairauch@ness.com
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.math.*;
import java.util.*;
import java.applet.*;
public class ecg extends JFrame
{
myView view = new myView();
Vector vr= new Vector();
datatread;
public ecg()
{
setBounds(3,10,625,350);
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent ev)
{dispose();
System.exit(0);}});
getContentPane().add(view);
getContentPane().setLayout(null);
tread = new data(vr);
setVisible(true);
while (true)
{
try
{
view.move_1();
repaint();
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
public class myView extends JComponent
{
BufferedImage I;
Graphics2D G;
Point p1;
Point p2;
intwidth= 600;
inthight= 301;
intpoint_s = 4;
Color bcolor = new Color(220,180,160);
public myView()
{
setBackground(bcolor);
setBounds(10,10,width,hight);
I = new BufferedImage(width,hight,BufferedImage.TYPE_INT_ARGB);
G = I.createGraphics();
G.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
clear(0,width);
}
public void move_1()
{
if (vr.size() < 2) return;
G.drawImage(I,0,0,width-point_s,hight,point_s,0,width,hight,null);
clear(width-point_s,point_s);
p1 = (Point)vr.get(0);
p2 = (Point)vr.get(1);
G.setColor(Color.darkGray);
G.drawLine(width-point_s-1,p1.y+hight/2,width-1,p2.y+hight/2);
vr.remove(0);
}
public void clear(int x, int w)
{
G.setColor(bcolor);
G.fillRect(x,0,w,hight);
G.setColor(Color.lightGray);
for (int y=0; y < 11; y++) G.fillRect(x,y*30,w,1);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(I,0,0,null);
}
}
public class data extends Thread
{
Vector dv;
public data(Vector v)
{
super();
dv = v;
this.start();
}
public void run()
{
while (true)
{
try
{
while (dv.size() < 240)
{
int p = (int)(Math.random() * 260);
dv.add(new Point(0,p-130));
}
Thread.sleep(2000);
} catch (InterruptedException e) {}
}
}
}
public static void main (String[] args)
{
new ecg();
}
}
--
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.math.*;
import java.util.*;
import java.applet.*;
public class ecg extends JFrame
{
myView view = new myView();
Vector vr= new Vector();
datatread;
public ecg()
{
setBounds(3,10,625,350);
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent ev)
{dispose();
System.exit(0);}});
getContentPane().add(view);
getContentPane().setLayout(null);
tread = new data(vr);
setVisible(true);
while (true)
{
try
{
view.move_1();
repaint();
Thread.sleep(100);
} catch (InterruptedException e) {}
}
}
public class myView extends JComponent
{
BufferedImage I;
Graphics2D G;
Point p1;
Point p2;
intwidth= 600;
inthight= 301;
intpoint_s = 4;
Color bcolor = new Color(220,180,160);
public myView()
{
setBackground(bcolor);
setBounds(10,10,width,hight);
I = new BufferedImage(width,hight,BufferedImage.TYPE_INT_ARGB);
G = I.createGraphics();
G.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
clear(0,width);
}
public void move_1()
{
if (vr.size() < 2) return;
G.drawImage(I,0,0,width-point_s,hight,point_s,0,width,hight,null);
clear(width-point_s,point_s);
p1 = (Point)vr.get(0);
p2 = (Point)vr.get(1);
G.setColor(Color.darkGray);
G.drawLine(width-point_s-1,p1.y+hight/2,width-1,p2.y+hight/2);
vr.remove(0);
}
public void clear(int x, int w)
{
G.setColor(bcolor);
G.fillRect(x,0,w,hight);
G.setColor(Color.lightGray);
for (int y=0; y < 11; y++) G.fillRect(x,y*30,w,1);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(I,0,0,null);
}
}
public class data extends Thread
{
Vector dv;
public data(Vector v)
{
super();
dv = v;
this.start();
}
public void run()
{
while (true)
{
try
{
while (dv.size() < 240)
{
int p = (int)(Math.random() * 260);
dv.add(new Point(0,p-130));
}
Thread.sleep(2000);
} catch (InterruptedException e) {}
}
}
}
public static void main (String[] args)
{
new ecg();
}
}
Animation can be accomplished by erasing the original drawing, then quickly drawing the new image.
For example, you could have some code like this:
static final long pause=40; // 25 frames per second produces smooth animation
volatile boolean stillMoving; // a boolean value to control whether the animation is still running
public void animate(Graphics g) {
stillMoving = true;
do {
g.setColor(Color.white); // clear the screen
g.fillrect(0,0,g.getSize().width,g.getSize().height);
redraw(g);// redraw the image - don't take too long!
try {
Thread.sleep(pause); // pause for a while, or the animation will go too fast
} catch (InterruptedException ie) {
}
} while (stillMoving); // keep going until the boolean value changes
}
public void stopAnimation() {
stillMoving = false;// this will stop the running animation
}
public void redraw(Graphics g) {
drawSinWave(g); // you write this one!
}
This code should run in a separate Thread (are you familiar with Threads?), for various reasons... the main one being that if not, there is no way to stop the animation.
public class MyAnim implements Runnable {
Graphics g; // the Graphics object on which to work
public MyAnim(Graphics g) {
this.g = g;
}
public void run() {
animate(g);
}
// insert the code above here
}
Then, in another class somewhere else:
Graphics g = o.getGraphics() ;// get a Graphics object from o
MyAnim anim = new MyAnim(g); // create the Animator
Thread t = new Thread(anim); // create the Thread that the ANimator will run in
t.start();// start the thread!
...
anim.stopAnimation(); // stop the animation
All you really need is the Graphics class, (and the class you get the Graphics object from) and the technique of
do { draw - pause - erase - redraw } while (..). Personally I think doing it in a Thread is best, so you'd need Threads as well...
Animation afficiandos will tell you that you should use "double buffering" to get a smoother animation. They are right, but I can't help you there. Double buffering is the following technique: draw - pause - draw next frame "off-screen" - copy the drawn frame onscreen.
You can see what animation (without double buffering) looks like in java at http://www.angelfire.com/mt/ofolives/DotPlacer.html - (but no source code there I'm afraid.)