Issue with refresh of JFreechart

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
manjusha0110
Posts: 10
Joined: Tue May 02, 2017 7:24 am
antibot: No, of course not.

Issue with refresh of JFreechart

Post by manjusha0110 » Thu Nov 23, 2017 6:38 am

Please help me...I have recently started using JFreechart and i am facing some problems.
I am adding a point to the series in Jfreechart (scatter chart) and then putting the thread to sleep for 3 seconds. I want to simultaneously show the point on the jfreechart. The above logic is in a loop, so i want a delay of 3 secs before plotting the next point.

The problem i am facing is, the point is not displayed on the chart immediately, only once the entire loop is executed all the points are shown.
I have also called revalidate and refresh but its not working.

Can anyone please please help me...I am not able to find the solution.

Below is my code :-

do {
double valX1,valY1;
valX1 = fRandom.nextGaussian();
valY1 = fRandom.nextGaussian();
double valX = Math.round(valX1 * 100.0) / 100.0;
double valY = Math.round(valY1 * 100.0) / 100.0;


double ptx1 = ((valX - xc) * tankRange)/1000;
double pty1 = ((valY - yc) * tankRange)/1000;

ptx=Math.round(ptx1 * 100.0) / 100.0;
pty=Math.round(pty1 * 100.0) / 100.0;

if ((ptx >= -(Et.getTurretWd()/2) && ptx <= Et.getTurretWd()/2) && (pty >= -(Et.getTurretHt()/2) && pty <= (Et.getTurretHt()/2))){
hitCnt++;
series.add(ptx, pty);
chartPanel.repaint();
chartPanel.revalidate();
isHit = true;
//insert into rounds table with flag as 'H' and exit the loop
try {
String strqry1 = "Insert into RoundDet (ShootId,TankID,HitMiss, XCoord, YCoord, Createddate, Modifieddate) values (" + shootid + "," + Ot.Tankid + ", 'H' ," + ptx + "," + pty + ",'" + sqlDate + "' ,'" + sqlDate +"')";
System.out.println(strqry1);
stmt.execute(strqry1);

} catch (SQLException e) {
e.printStackTrace();
} finally {
}
break;

} else {
series1.add(ptx, pty);
chartPanel.repaint();
chartPanel.revalidate();

}

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: Issue with refresh of JFreechart

Post by paradoxoff » Thu Nov 23, 2017 9:57 am

Do you call your method from an ActionListener? If yes, then your while loop is executing in the event dispatching thread, and the GUI will only be updated after the loop is completed.

You need to run the code that is updating the dataset outside the event dispatching thread, and trigger an event when an update cycle is complete and the gui needs to be updated. Here is an example:

Code: Select all

package jfree;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import org.jfree.data.xy.AbstractXYDataset;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.SamplingXYLineRenderer;
import org.jfree.chart.renderer.xy.SamplingXYLineAndShapeRenderer;
import java.util.Random;
import org.jfree.data.DomainOrder;
import javax.swing.Timer;

public class AutoUpdatingDatasetDemo {

    public static void main(String[] args) {
        int max = 1000;
        int delay = 50;
        AutoUpdatingDataset dataset = new AutoUpdatingDataset("Auto Data", max, delay, 50);
        DateAxis dateAxis = new DateAxis("Date");
        NumberAxis rangeAxis = new NumberAxis("Value");
        long now = System.currentTimeMillis();
        dateAxis.setAutoRange(false);
        rangeAxis.setAutoRange(false);
        SamplingXYLineAndShapeRenderer renderer = new SamplingXYLineAndShapeRenderer(false, true);
        renderer.setSeriesShape(0, new Ellipse2D.Double(-2,-2, 4, 4));
        renderer.setSeriesPaint(0, Color.blue);
        
        XYPlot plot = new XYPlot(dataset, dateAxis, rangeAxis, renderer);
        plot.setDomainMinorGridlinesVisible(true);
        plot.setDomainPannable(true);
        JFreeChart chart = new JFreeChart(plot);
        JFrame frame = new JFrame("Auto Update Demo");
        ChartPanel cp = new ChartPanel(chart);
        cp.setMouseWheelEnabled(true);
        frame.getContentPane().add(cp);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
        dateAxis.setLowerBound(now);
        dateAxis.setUpperBound(now + max*delay);
        rangeAxis.setLowerBound(-1.2);
        rangeAxis.setUpperBound(1.2);
        dataset.start();
    }
}

class AutoUpdatingDataset extends AbstractXYDataset implements ActionListener {

    private String name;
    private int max;
    private long delay;
    private long visualDelay;
    private double[][] values;
    private int cursor = -1;
    long first;
    private Timer timer;
    private Random random = new Random();
    private long lastEvent;
    private long period;
    private double yDataMax = Math.PI*10;

    AutoUpdatingDataset(String name, int max, int delay, int visualDelay) {
        this.name = name;
        this.max = max;
        this.delay = delay;
        this.visualDelay = visualDelay;
        this.values = new double[max][2];
        timer = new Timer(delay, this);
        lastEvent = System.currentTimeMillis();
       
    }

    public DomainOrder getDomainOrder() {
        return DomainOrder.ASCENDING;
    }

    public int getSeriesCount() {
        return 1;
    }

    public Comparable getSeriesKey(int series) {
        return name;
    }

    public int getItemCount(int series) {
        return cursor;
    }

    public double getYValue(int series, int item) {
        return values[item][1];
    }

    public double getXValue(int series, int item) {
        return values[item][0];
    }

    public Double getY(int series, int item) {
        return new Double(getYValue(series, item));
    }

    public Double getX(int series, int item) {
        return new Double(getXValue(series, item));
    }

    public void actionPerformed(ActionEvent ae) {
        if (cursor >= max - 1) {
            timer.stop();
            return;
        }
        cursor++;
        long now = System.currentTimeMillis();
        values[cursor][0] = now;
        values[cursor][1] = Math.sin(yDataMax/max*cursor);
        if (now - lastEvent > visualDelay) {
            lastEvent = now;
            fireDatasetChanged();
        }
    }

    public void start() {
        timer.start();
    }
}

Locked