0

I am trying to generate a chart dynamically that will show the value change over time. I am storing those value in an ArrayList< Integer, ArrayList<Integer>> and retrieving those values in this class. But it doesn't show the addition of the values in that ArrayList over time.

Here actually another two thread is updating that ArrayList and I need to show the values of that Arraylist in a chart that will be dynamic.

The below is the code based on this example:

package com.model.presentation;

import java.awt.BorderLayout;
import java.awt.Dimension;
//import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
//import java.util.Random;
import java.util.Map.Entry;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.Timer;

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.category.DefaultCategoryDataset;

import com.model.resources.Household;

/**
 * @see https://stackoverflow.com/a/15715096/230513
 * @see https://stackoverflow.com/a/11949899/230513
 */

public class DisplayChart {

    //private static final int N = 128;
    //private static final Random random = new Random();
    private int n = 1;
    static int count = 0;

    public void display() 
    {
        JFrame f = new JFrame("Community Rescilience Model");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JTabbedPane jtp = new JTabbedPane();
        jtp.add(String.valueOf(n), createPane());
        f.add(jtp, BorderLayout.CENTER);
        JPanel p = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        p.add(new JButton(new AbstractAction("Add") {
            public void actionPerformed(ActionEvent e) {
                jtp.add(String.valueOf(++n), createPane());
                jtp.setSelectedIndex(n - 1);
            }
        }));
        f.add(p, BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private ChartPanel createPane() 
    {
        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        final String name = "Community ";

       /* for (int i = 0; i < random.nextInt(N) + N / 2; i++) 
        {

            while (iterator.hasNext()) 
            {
                Map.Entry map = (Map.Entry) iterator.next();
                String community_name =  name + String.valueOf(map.getKey());
                ArrayList<Integer> dataArrayList = (ArrayList<Integer>) map.getValue();
                for (Iterator<Integer> it = dataArrayList.iterator(); it.hasNext();)
                {
                    dataset.addValue(it.next(), community_name, String.valueOf(count));
                    count++;
                }
            }
         }*/
       // XYSeriesCollection dataset = new XYSeriesCollection(series);
        new Timer(100, new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {
                Iterator<Entry<Integer, ArrayList<Integer>>> iterator = Household.goods.entrySet()
                        .iterator();
                while (iterator.hasNext()) 
                {
                    Map.Entry map = (Map.Entry) iterator.next();
                    String community_name =  name + String.valueOf(map.getKey());
                    ArrayList<Integer> dataArrayList = (ArrayList<Integer>) map.getValue();
                    for (Iterator<Integer> it = dataArrayList.iterator(); it.hasNext();)
                    {
                        dataset.setValue(it.next(), community_name, String.valueOf(count));
                        count++;
                    }
                 }
                }

         }).start();
        JFreeChart lineChart = ChartFactory.createLineChart("Resource Production/Consumption over time", "Time",
                "Number of GOODS", dataset, PlotOrientation.VERTICAL,
                true, true, false);
        return new ChartPanel(lineChart) {
            @Override
            public Dimension getPreferredSize() 
            {
                return new Dimension(1000, 500);
            }
        };
    }


    /*public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DisplayChart().display();
            }
        });
    }
}*/

}

The main class is :

public class Main_class {

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            new DisplayChart().display();
        }
    });
}

This code works but at certain point, it gets stuck. It means it does not show the value of the changes in that Arraylist.

Community
  • 1
  • 1
sohan
  • 577
  • 1
  • 6
  • 9

1 Answers1

1

I have it running indefinitely although i am not sure it is still working as you intended.

I didn't have the Household class so I just faked it with.

class Household {
    static public Map<Integer, ArrayList<Integer>> goods = new HashMap<>();
}

I also don't think I have your code for adding data to the plot. I did it like this:

Random rand = new Random();
while (true) {
    try {
        Thread.sleep(100);
        for (int i = 0; i < 10; i++) {
            final int fi = i;
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    ArrayList<Integer> l = Household.goods.get(fi);
                    if (l == null) {
                        l = new ArrayList<>();
                    }
                    l.add(rand.nextInt(100));
                    if (l.size() > 20) {
                        l.remove(0);
                    }
                    Household.goods.put(fi, l);
                }
            });
        }
    } catch (InterruptedException ex) {
    }
}

Note that it is important to do it in the EventQueue thread or you will get a ConcurrentModificationException.

The real issue seems to be that your adding the same data in the list over and over again associated with different counts.

So I changed:

    for (Iterator<Integer> it = dataArrayList.iterator(); it.hasNext();)
    {
           dataset.setValue(it.next(), community_name, String.valueOf(count));
           count++;
     }

To :

for (count = 0; count < dataArrayList.size(); count++) {
    dataset.setValue(dataArrayList.get(count), community_name, String.valueOf(count));
}
WillShackleford
  • 6,918
  • 2
  • 17
  • 33
  • For reference, the complete original program is seen [here](http://stackoverflow.com/a/15715096/230513). – trashgod Aug 21 '15 at 01:49