具有原始线图函数 Java 的动画线图

发布于 2024-08-08 10:53:29 字数 4308 浏览 3 评论 0原文

为了更多地了解小程序和 Java,我正在尝试通过绘制线条 (drawLine) 和制作动画折线图来制作波形小程序。

我可以很好地制作静态图。然而,我正在努力解决图表的动画方面:图表的轴应该从左向右移动,增加并增长到大于 0。

我的问题是将我的需求转化为解决方案。任何人都可以给我任何关于我的问题的指示吗?

我有一个多维数组,由包含特定点的 x 和 y 的点索引。我尝试修改我的渲染函数以减少 X,使其看起来好像向左移动,但这不起作用。

我希望采取什么方法?如果 Y 的值可能因用户操作或添加的数据而改变,我的方法会有多大不同?

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);
}
    }

}

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);
}
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不醒的梦 2024-08-15 10:53:29

首先,看起来您在 updateSeries 方法中过于频繁地减去衰减。
以下是该方法的新版本。

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;
    }

通过这些更改,线条绘制得更好,但绘制速度太慢,以至于很难看清动画。您可能需要构建一个新图形并交换整个图形,这样您就不必观看绘制的每个单独的线段。

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.

浅忆 2024-08-15 10:53:29

对于初学者,您可以查看以下示例(以及与此相关的示例)

滚动图表@java2s.com

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

Scroll Chart @java2s.com

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文