Cristophs0n
Cristophs0n

Reputation: 1266

JFreeChart: update/repaint line graph when a new value is received from another class

This is only my second post, so please forgive me if I am not following the rules correctly yet. I am trying to automatically update a line graph, which was created using the JFreeChart lib. I have been attempting this for a few days now and have referred to the api and followed many examples here, here and here.

I have a method that gets the balance of an account and sends it to another class:

public double credit(double d) 
{
    int bonus = 10;
    if (d >= 500){
        logData = "CREDITED: + £" + df.format(d) + "\n ********** Whohoo a £10.00 bonus has been added to your balance for depositing at least £500 in a single month **********\n";
        currentBalance = currentBalance + d + bonus;
        draw.passBalance(currentBalance);
        draw.paint(currentBalance); //Send balance to Draw class for the graph (CPB)
    } else {
        logData = "CREDITED: + £" + df.format(d) + "\n";
        currentBalance = currentBalance + d;
    } 
    return currentBalance;
}

The class that receives this deals with the data for the graph:

public class Draw extends ApplicationFrame {

private double balance;
private ChartPanel chartPanel;
private JFreeChart chart;
private XYDataset dataset;
private Draw graph;

    public Draw(final String title) {

        super(title);

        dataset = createDataset();
        chart = createChart(dataset);
        chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(750, 350));
        setContentPane(chartPanel);
    }

    private XYDataset createDataset() {

        final XYSeries series1 = new XYSeries("Balance");
        series1.add(1.0, balance);
        series1.add(2.0, balance);
        series1.add(3.0, 100.00);
        series1.add(4.0, 100.00);
        series1.add(5.0, 100.00);
        series1.add(6.0, 100.00);
        series1.add(7.0, 100.00);
        series1.add(8.0, 100.00);
        series1.add(9.0, 100.00);
        series1.add(10.0, 100.00);
        series1.add(11.0, 100.00);
        series1.add(12.0, 100.00);

        System.out.println(balance);

        final XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series1);

        return dataset;
    }

    private JFreeChart createChart(final XYDataset dataset) {

      // create the chart...
      final JFreeChart chart = ChartFactory.createXYLineChart(
            "Account Balance", // chart title
            "Month", // x axis label
            "Balance", // y axis label
            dataset, // data
            PlotOrientation.VERTICAL,
            false, // include legend
            true, // tooltips
            false // urls
    );


      chart.setBackgroundPaint(Color.white);

      final XYPlot plot = chart.getXYPlot();
      plot.setBackgroundPaint(Color.white);
      plot.setDomainGridlinePaint(Color.lightGray);
      plot.setRangeGridlinePaint(Color.lightGray);

      final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
      renderer.setSeriesLinesVisible(1, true);
      plot.setRenderer(renderer);

      return chart;

  }

    public double passBalance(double d)
    {
     return balance = d;
    }

    public void paint(double d)
    {   
        //System.out.println(balance);
        createDataset();

    }
}

It is my understanding that the chart will be redrawn since all the methods throw a SeriesChangeEvent, but this doesn't appear to be the case.

I'm relatively new to Java and would greatly appreciate any help at all!!!

Thanks

Upvotes: 3

Views: 2616

Answers (1)

trashgod
trashgod

Reputation: 205785

To help isolate the problem, I've reduced your code to a self-contained example that updates a single XYDataItem in an XYSeries in an XYSeriesCollection. Note that each XYDataItem encapsulates two instances of Number; each are Comparable, as required by the XYSeries; add(double x, double y) converts each to Double. Click the Update button to see the effect. Item INDEX should increase by five with each click.

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;

/** @see https://stackoverflow.com/a/33898324/230513 */
public class Draw extends ApplicationFrame {

    private static final int INDEX = 5;
    private final XYSeries series = new XYSeries("Balance");
    private double balance;

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            new Draw("Test");
        });
    }

    public Draw(final String title) {
        super(title);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        ChartPanel chartPanel = new ChartPanel(createChart(createDataset())) {

            @Override
            public Dimension getPreferredSize() {
                return new Dimension(640, 360);
            }
        };
        add(chartPanel);
        add(new JButton(new AbstractAction("Update") {

            @Override
            public void actionPerformed(ActionEvent e) {
                balance += 5;
                series.addOrUpdate(INDEX, balance);
            }
        }), BorderLayout.SOUTH);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private XYDataset createDataset() {
        for (int i = 0; i < 11; i++) {
            series.add(i, 100.00);
        }
        series.remove(INDEX);
        series.add(INDEX, balance);
        final XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(series);
        return dataset;
    }

    private JFreeChart createChart(final XYDataset dataset) {
        final JFreeChart chart = ChartFactory.createXYLineChart(
            "Account Balance", // chart title
            "Month", // x axis label
            "Balance", // y axis label
            dataset, // data
            PlotOrientation.VERTICAL,
            false, // include legend
            true, // tooltips
            false // urls
        );
        return chart;
    }
}

Upvotes: 1

Related Questions