tags:

views:

116

answers:

2

In the effort to learn more about applets and Java, I am experimenting making wave applets by drawing lines (drawLine) and making animated line graphs.

I can make a static graph just fine. However I am struggling with the animated aspect of the graph: the axes of the graph should move from left to right, increasing and growing larger than 0.

My problem is translating my needs into a solution. Can anyone give me any pointers with my problem?

I have a multidimensional array indexed by points containing the x and y of a particular point. I have tried modifying my render function to decrease the Xs to make it appear as if it is moving left but this doesn't work right.

What approach am I looking to take? How different will my approach be if the values of Y could change due to user action or added data?

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;

/**
 * A graph that should in the future represent a wave according to my inputs
 * 
 * @authorImprofane
 * @version 1
 */
public class Graph extends JFrame
{
    private InnerGraph inner;

    private int width;
    private Random RNG;
    private int height;
    private int[][] series;

    private int xoffset;
    int prevx = 0;
    int prevy = 0;



    /**
     * Constructor for objects of class Graph
     */
    public Graph(int width, int height) throws InterruptedException
    {
         RNG = new Random();
         setTitle(" Graph");

         series = new int[width][2];

         this.width = width;
         this.height = height;
         inner = new InnerGraph(width, height);

         add(inner, BorderLayout.CENTER);

         setVisible(true);
         inner.preparePaint();
         pack();
         updateGraph();
    }

    public static void main(String[] args) throws InterruptedException
    {
        new Graph(300, 300);
    }

    public void updateGraph() throws InterruptedException
    {   

        // virtual x is how far along on the x axis we are, I ignore the 'real' X axis
        int vx = 0;
        int point = 0;
        int xdecay = 0;
        int inc = 5;

        // how many times we need to plot a point
        int points = (int) java.lang.Math.floor( width / inc );
            System.out.println(points);
            inner.preparePaint();
            // draw all points to graph

            // make some junk data, a saw like graph
            for (vx = 0 ; vx < points ; vx++) {
                series[vx] = new int[] { vx*inc, ( (vx*inc) % 120 ) };
            }

            Thread.sleep(150);
            int n = 5;

        while(n > 0) {
            System.out.println(xdecay);
            inner.preparePaint();
                for (vx = 0 ; vx < points ; vx++) {
                    inner.updateSeries(vx, xdecay);

                    inner.repaint();
                    Thread.sleep(50);
                }
                xdecay += inc;

                // shift the data points to the left
                int[][] nseries = new int[points][2];
                // System.arraycopy(series, 1, nseries, 0, points-1);
                n--;
            }

    }

    public class InnerGraph extends JPanel
    {
        private Graphics g;
        private Image img;

        private int gwidth;
        private int gheight;

        Dimension size;

        public InnerGraph(int width, int height)
        {
            gwidth = width;
            gheight = height;
            size = new Dimension(1, 1);


        }

        /**
         * Try make panel the requested size.
         */
        public Dimension getPreferredSize()
        {
            return new Dimension(gwidth, gheight);
        }

        /**
         * Create an image and graphics context
         * 
         */

        public void preparePaint()
        {          
            size = getSize();
            img = inner.createImage( (size.width | gwidth), (size.height | gheight) );
            g = img.getGraphics();


        }

        /**
         * Draw a point to the chart given the point to use and the decay. 
         * Yes this is bad coding style until I work out the mathematics needed
         * to do what I want.
         */

        public void updateSeries(int point, int decay)
        {
            g.setColor(Color.blue);
            int nx = series[point][0];

            series[point][0] -= decay;
            if ( point-1 >= 0 ) {
                series[point-1][0] -= decay;
            }

            int ny = series[point][1];
            prevx -= decay;

            g.drawLine(prevx-decay, prevy, nx-decay, ny );         
            prevx = nx-decay;
            prevy = ny;
        }


        public void paintComponent(Graphics g)
        {
                    g.drawImage(img, 0, 0, null);
}
    }

}
A: 

For a starter you could check out the following example (and the ones related to this)

Scroll Chart @java2s.com

jitter
+1  A: 

First, it looks like you are subtracting the decay too often in the updateSeries method. Below is a new version of that method.

public void updateSeries(int point, int decay)
    {

        g.setColor(Color.blue);
        int nx = series[point][0];

        series[point][0] -= decay;
        if ( point-1 >= 0 ) {
            series[point-1][0] -= decay;
        }

        int ny = series[point][1];
    //    prevx -= decay;

    //    g.drawLine(prevx-decay, prevy, nx-decay, ny );         
    g.drawLine(prevx, prevy, nx-decay, ny );     
        prevx = nx-decay;
        prevy = ny;
    }

With those changes, the lines draw better, but they draw so slowly that the animation is hard to see. You probably need to build a new graphics and swap the whole thing so that you don't have to watch each individual line segment being drawn.

G_A