title: Multiple graphs in multiple figures using jFreeChart
body: <p>I am trying to use jFreechart to generate two figures each of which with 12 graphs (being referred as series in jFreeChart ). However some of the graphs get simply skipped! I know I have synchronization issue here and tried to used the method the user @trashgod provided me <a href="https://stackoverflow.com/questions/20056614/timing-issue-with-plotting-multiple-graphs-fast">here</a> however I failed.  I know <strong>the way I use swingworker is wrong</strong>! I dont know how to fix it</p>
  
  <p>Each figure should contain 10 graphs which are parallel horizontal straight lines. As you see in the attached image some of the lines are missing. The two figures have to be identical too ( which are not). In practice I will have to generate multiple graphs in several locations of my applications at various times(random time interval between each figure and even graphs of individual figures) 
  Any help will be very much appreciated </p>
  
  <pre><code>Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: This dataset already contains a series with the key Plot 11
      at org.jfree.data.xy.XYSeriesCollection.addSeries(XYSeriesCollection.java:154)
      at swing.FastChart2$MySwingWorker.process(FastChart2.java:192)
      at javax.swing.SwingWorker$3.run(SwingWorker.java:414)
      at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
      at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(SwingWorker.java:832)
      at sun.swing.AccumulativeRunnable.run(AccumulativeRunnable.java:112)
      at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(SwingWorker.java:842)
      at javax.swing.Timer.fireActionPerformed(Timer.java:312)
      at javax.swing.Timer$DoPostEvent.run(Timer.java:244)
      at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
      at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:733)
      at java.awt.EventQueue.access$200(EventQueue.java:103)
      at java.awt.EventQueue$3.run(EventQueue.java:694)
      at java.awt.EventQueue$3.run(EventQueue.java:692)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:703)
      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:91) 
  </code></pre>
  
  <p><img src="https://i.stack.imgur.com/00t0j.png" alt="enter image description here"></p>
  
  <pre><code>package swing;
  import java.awt.BorderLayout;
  import java.awt.Color;
  import java.awt.EventQueue;
  import java.awt.Rectangle;
  import java.awt.Shape;
  import java.awt.geom.Ellipse2D;
  import java.beans.PropertyChangeEvent;
  import java.beans.PropertyChangeListener;
  import java.io.IOException;
  import java.util.List;
  import javax.swing.JFrame;
  import javax.swing.JPanel;
  import javax.swing.SwingWorker;
  import org.jfree.chart.*;
  import org.jfree.chart.axis.NumberAxis;
  import org.jfree.chart.plot.PlotOrientation;
  import org.jfree.chart.plot.XYPlot;
  import org.jfree.chart.renderer.xy.XYItemRenderer;
  import org.jfree.data.xy.XYSeries;
  import org.jfree.data.xy.XYSeriesCollection;
  import org.jfree.util.ShapeUtilities;
  
  public class FastChart2 extends JFrame {
     private XYSeries [] xySeries ;
     private XYPlot xyPlot;
     private XYSeriesCollection xySeriesCollection;
     private String title;
     private static int instanceNum=0;
     private int figNum=0;
  
     private ChartPanel chartPanel;
  
     public  FastChart2(String s) {
        super(s);
        figNum = instanceNum;
        instanceNum++;
        init(s);
     }
  
     private void init(String s){
        title = s;
        xySeries = new XYSeries[12];
        for (int i = 0; i &lt; xySeries.length; i++) {
           xySeries[i]    = new XYSeries("Plot "+i);  
        }
        xySeriesCollection = new XYSeriesCollection();
        JFreeChart chart = ChartFactory.createScatterPlot(
              title, "X", "Y", xySeriesCollection,
              PlotOrientation.VERTICAL, true, true, false);
  
        xyPlot =  chart.getXYPlot();
        xyPlot.setDomainCrosshairVisible(true);
        xyPlot.setRangeCrosshairVisible(true);
  
        chartPanel = createChartPanel(chart);
  
        add(chartPanel, BorderLayout.CENTER);
        JPanel control = new JPanel();
  
        add(control, BorderLayout.SOUTH);
  
        setDefaultCloseOperation(DISPOSE_ON_CLOSE); 
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
     }
  
     private  ChartPanel createChartPanel(JFreeChart chart) {
  
        XYItemRenderer renderer = xyPlot.getRenderer();
        renderer.setSeriesPaint(0, Color.magenta);
        renderer.setSeriesPaint(1, Color.green);
        renderer.setSeriesPaint(2, Color.blue);
        renderer.setSeriesPaint(4, Color.black);
        renderer.setSeriesPaint(3, Color.yellow);
        Shape cross = ShapeUtilities.createDiagonalCross(3, 0);
        Shape plus = ShapeUtilities.createRegularCross(4,0);
  
        for (int i = 0; i &lt;=3; i++) {
           renderer.setSeriesShape(0+i,    new Rectangle(-1, -1, 2, 2));
           renderer.setSeriesShape(4+i,    new Ellipse2D.Float(-2F, -2F, 5F, 5F));  
           renderer.setSeriesShape(8+i,    cross);
        }
        NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis();
        domain.setRange(0,1000);
        NumberAxis range = (NumberAxis) xyPlot.getRangeAxis();
        range.setRange(0,1200);
        return new ChartPanel(chart);
     }
  
  
     public  void multiPlot(){
        Thread thread = null;
        thread = new Thread (){
           public void run() {
              final double [] x = new double[1000];
              final double [] y = new double[1000];
  
              try{    
                 for (int k = 0; k &lt; 12; k++) {
  
                    for (int i = 0; i &lt; y.length; i++) {
                       x[i] = i;
                       y[i] = k*100;
                    }
  
                    try {
                       Thread.sleep(100);
                    } catch (InterruptedException e) {
                    }
  
                    plot2d(k % 12, x, y," Fig:"+figNum+" Seri:"+k);
                 }
              } catch (Exception e){
                 System.out.println();
              }     
           }
        };
        thread.start();
     }
  
  
     public synchronized void plot2d( final int iSeriesN,  final double [] dX,  final double [] dY, final String sT){
  
        if (dY.length != dX.length){
           throw new IllegalArgumentException("Error! inputs x and y have to be of same size.");
        }
  
              MySwingWorker mySwingWorker = new MySwingWorker( iSeriesN, dX, dY, sT);
  
              mySwingWorker
              .addPropertyChangeListener(new PropertyChangeListener() {
  
                 public void propertyChange(PropertyChangeEvent pcEvt) {
                    if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) {
                      System.out.println("done");
                    }
                   if ("progress".equals(pcEvt.getPropertyName())) {
                       System.out.println("progress");
                     }
                 }
              });
  
              mySwingWorker.execute(); 
  
     }
  
     private class MySwingWorker extends SwingWorker&lt;Void, Double&gt; {
  
        private double [] dX ;
        private double [] dY ;
        private String title;
        private int iSeriesN;
        private MySwingWorker(int iSeriesN, double [] ix, double[] iy, String st){
          dX = ix.clone();
          dY = iy.clone();
          title= st;
          this.iSeriesN = iSeriesN;
          xySeriesCollection.removeAllSeries();
          System.out.println("xySeriesCollection.removeAllSeries();");
        }
  
        @Override
        public Void doInBackground() throws IOException {
  
      //    chartPanel.getChart().removeChangeListener((ChartChangeListener) chartPanel);
  
  
           xySeries[iSeriesN].clear();
           for (int i = 0; i &lt; dX.length; i++) {
              xySeries[iSeriesN].add(dX[i], dY[i]);
           }
  
           for (int i = 0; i &lt; xySeries.length; i++) {
              setProgress(i * (100 / xySeries.length));
              publish(Double.valueOf(i));
              try {
                 Thread.sleep(10);
              } catch (InterruptedException e) {
              } // simulate latency
  
          }
           return null;
        }
  
  
        @Override
        protected void process(List&lt;Double&gt; chunks) {
           for (double d : chunks) {
              xySeriesCollection.addSeries(xySeries[(int) d]);
          }
  
        }
        @Override
        protected void done() {
            try {
  
  
       //        chartPanel.getChart().addChangeListener((ChartChangeListener) chartPanel);
               xySeries[iSeriesN].setKey(title);
  
            } catch (Exception ignore) {
            }
        }
     }
  
     public XYSeries addXY(final int iSeriesN, final double [] dX, final double [] dY){
        XYSeries series = new XYSeries("Plot ");
  
        for (int i = 0; i &lt; dX.length; i++) {
           series.add(dX[i], dY[i]);
        }
        return series;
     }
  
     public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
           @Override
           public void run() {
              FastChart2 [] demo = new FastChart2[2];
              for (int i = 0; i &lt; demo.length; i++) {
                 demo[i] = new FastChart2("Figure "+i);
                 demo[i].multiPlot();
  
              } 
  
           }
        });
     }
  }
  </code></pre>