JFreeChart图表滞后

时间:2014-06-27 23:37:21

标签: java multithreading jfreechart

该程序应该通过使用线程来移动正弦波并对其进行动画处理。 XYSeries中绘制波形的点。几秒钟后,图表开始闪烁并随机放大和缩小。我不知道这是我的代码还是我的电脑(可能是代码)的问题。

import java.awt.geom.Point2D;
import static java.lang.Math.PI;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class WaveGraph extends JFrame
{
    double numOfWaves = 2;
    double waveAmp = 2;
    double waveLength = 10;
    double waveRes = 20;
    double median = ((waveLength*numOfWaves)/2);
    int numOfPoints = (int)(numOfWaves*waveRes);
    boolean going = true;
    boolean left = true;
    XYSeriesCollection dataset = new XYSeriesCollection();
    Point2D.Double[] points;

WaveGraph()
{
    XYSeries buoys = new XYSeries("Buoys");
    XYSeries series = new XYSeries("Wave");
    points = new Point2D.Double[numOfPoints];
    for(int i=0; i<numOfPoints; i++)
    {
        Point2D.Double temp = new Point2D.Double();
        temp.x = i*(waveLength/waveRes);
        temp.y = waveAmp*Math.sin((2*PI)/waveLength*temp.x);
        points[i] = temp;
        series.add(points[i].x, points[i].y);
        if(i==(numOfPoints/2)-1)
            buoys.add(median, points[i].y);
    }

    buoys.add(median, 0);
    dataset.addSeries(series);
    dataset.addSeries(buoys);
    JFreeChart chart = ChartFactory.createXYLineChart(
    "Sine Wave", // chart title
    "Wavelength(meters)", // x axis label
    "Amplitude (meters)", dataset, // data
    PlotOrientation.VERTICAL,
    false, // include legend
    false, // tooltips
    false // urls
    );
    XYPlot plot = (XYPlot)chart.getPlot();
    XYLineAndShapeRenderer renderer
    = (XYLineAndShapeRenderer) plot.getRenderer();
    renderer.setSeriesShapesFilled(1, true);
    renderer.setSeriesShapesVisible(1, true);
    NumberAxis domain = (NumberAxis)plot.getDomainAxis();
    domain.setRange(0.00, waveLength*numOfWaves);
    NumberAxis range = (NumberAxis)plot.getRangeAxis();
    range.setRange(-waveAmp*1.3, waveAmp*1.3);
    ChartPanel cp = new ChartPanel(chart);
    cp.setPreferredSize(new java.awt.Dimension(500, 270));
    setContentPane(cp);
    setDefaultCloseOperation(EXIT_ON_CLOSE);         
    pack();
    setLocationRelativeTo(null);
    setVisible(true);
    WaveRunner run = new WaveRunner();
}

class WaveRunner extends Thread
{
    WaveRunner()
    {
        this.start();
    }

    public void run()
    {
        double[] temp = new double[numOfPoints];
        XYSeries temp2, temp3;
        while(going)
        {
            temp2 = dataset.getSeries(0);
            temp3 = dataset.getSeries(1);
            temp2.delete(0, numOfPoints-1);
            temp3.delete(0, 1);
            for(int i=0; i<numOfPoints; i++)
            {
                if(left){
                try{
                    temp[i] = points[i+1].y;
                }
                catch(java.lang.ArrayIndexOutOfBoundsException exc){
                    temp[numOfPoints-1] = points[0].y;
                }}
                else{
                try{
                    temp[i] = points[i-1].y;
                }
                catch(java.lang.ArrayIndexOutOfBoundsException exc){
                    temp[0] = points[numOfPoints-1].y;
                }}
            }
            for(int i=0; i<numOfPoints; i++)
            {
                points[i].y = temp[i];
                temp2.add(points[i].x, points[i].y);
                if(i==(numOfPoints/2))
                {    
                    temp3.add(median, points[i].y);
                    temp3.add(median, 0);
                }
            }
            try
            {
                Thread.sleep(50);
            }
            catch(InterruptedException exc)
            {}
        }    
    }
}

public static void main(String[] args)
{
    WaveGraph test = new WaveGraph();
}
}

1 个答案:

答案 0 :(得分:2)

您的示例未正确同步,因为它会从WaveRunner更新图表的数据集。图表的模型显示在ChartPanel中,因此应仅在event dispatch thread上更新 。相反,使用Swing Timer调整动画速度,如herehereSwingWorker所示,如here所示。