001    /**###########################################################################
002    ##                                                                          ##
003    ## JQuickPlot - Java Quick XY Plots                                         ##
004    ##                                                                          ##
005    ## Copyright (C) 2008  Frederic Roudaut  <frederic.roudaut@free.fr>         ##
006    ##                                                                          ##
007    ##                                                                          ##
008    ## This program is free software; you can redistribute it and/or modify it  ##
009    ## under the terms of the GNU General Public License version 2 as           ##
010    ## published by the Free Software Foundation; version 2.                    ##
011    ##                                                                          ##
012    ## This program is distributed in the hope that it will be useful, but      ##
013    ## WITHOUT ANY WARRANTY; without even the implied warranty of               ##
014    ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        ##
015    ## General Public License for more details.                                 ##
016    ##                                                                          ##
017    ############################################################################**/
018    
019    package JQuickPlot;
020    
021    import java.awt.BorderLayout;
022    import java.awt.Color;
023    import java.awt.FlowLayout;
024    import java.awt.Point;
025    import java.awt.event.ActionEvent;
026    import java.awt.event.ActionListener;
027    
028    import org.jdesktop.layout.GroupLayout;
029    
030    import javax.swing.BorderFactory;
031    import javax.swing.JButton;
032    import javax.swing.JPanel;
033    import javax.swing.JFrame;
034    import javax.swing.JTabbedPane;
035    import javax.swing.BoxLayout;
036    import javax.swing.SwingConstants;
037    
038    import org.jfree.chart.ChartPanel;
039    import org.jfree.chart.JFreeChart;
040    import org.jfree.chart.axis.DateAxis;
041    import org.jfree.chart.axis.NumberAxis;
042    import org.jfree.chart.axis.ValueAxis;
043    import org.jfree.chart.plot.CombinedDomainXYPlot;
044    import org.jfree.chart.plot.XYPlot;
045    import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
046    import org.jfree.chart.renderer.xy.*;
047    import org.jfree.data.xy.XYSeriesCollection;
048    import org.jfree.data.xy.XYSeries;
049    import org.jfree.ui.ApplicationFrame;
050    import org.jfree.ui.RefineryUtilities;
051    
052    import java.io.InputStream;
053    import java.io.InputStreamReader;
054    import java.io.FileInputStream;
055    import java.io.BufferedReader;
056    import java.lang.System;
057    
058    import java.util.HashMap;
059    
060    
061    /**
062     * The Main Class for JQuickPlot
063     *
064     */
065    public class  JQuickPlot extends ApplicationFrame implements ActionListener {
066    
067        /** The number of subplots per plots. **/
068        private int _nbSubplots = 0;  
069    
070        /** The number of plots **/
071        private int _nbPlots = 16;  
072    
073        /** Datasets List for plots **/
074        private XYSeriesCollection[] _datasets;    
075    
076        /** Columns List for X in plots **/
077        private ColumnList[] datasetColumnListX;
078    
079        /** Columns List for Y in plots **/
080        private ColumnList[] datasetColumnListY;
081    
082        /** Files List for Datasets of plots **/
083        private String[] _datasetFile;
084    
085        /** X Label for Datasets of plots **/
086        private String[] _labelX;
087    
088        /** Y Label for Datasets of plots **/
089        private String[] _labelY;
090    
091        /** plots List **/
092        private CombinedDomainXYPlot[] _plotList;
093    
094        /** subplots List per plot **/
095        private XYPlot[][] _subplotList;
096        
097        /* Renderer Constants */
098        /**
099           Standard renderer for the XYPlot class.
100        **/
101        public static final int ConstStandardXYItemRenderer = 0;
102    
103        /**
104           Standard renderer for the XYPlot class with dots.
105        **/
106        public static final int ConstDefaultXYItemRenderer = 1;
107    
108        /**
109           A XYLineAndShapeRenderer that adds a shadow line to the graph to emulate a 3D-effect.
110        **/
111        public static final int ConstXYLine3DRenderer = 2;
112    
113        /**
114           A Spline Renderer.
115        **/
116        public static final int ConstXYSplineRenderer = 3;
117    
118        /**
119           A renderer that draws a line connecting the start and end Y values for an XYPlot .
120        **/
121        public static final int ConstYIntervalRenderer = 4;
122    
123        /**
124           A renderer for an XYPlot that highlights the differences between two series. The renderer expects a dataset that:<br/>
125           - has exactly two series;<br/>
126           - each series has the same x-values;<br/>
127           - no null values; 
128        **/
129        public static final int ConstXYDifferenceRenderer = 5;
130    
131        /**
132           A renderer that draws a small dot at each data point for an XYPlot .
133        **/
134        public static final int ConstXYDotRenderer = 6;
135    
136        public static final int ConstXYErrorRenderer = 7;
137        public static final int ConstVectorRenderer = 8;
138        public static final int ConstDeviationRenderer = 9;
139    
140        /**
141           The Cyclic XY item renderer is specially designed to handle cyclic axis. While the standard renderer would
142           draw a line across the plot when a cycling occurs, the cyclic renderer splits the line at each cycle end instead.
143           This is done by interpolating new points at cycle boundary. Thus, correct appearance is restored. 
144           The Cyclic XY item renderer works exactly like a standard XY item renderer with non-cyclic axis.
145        **/
146        public static final int ConstCyclicXYItemRenderer = 10;
147    
148        /**
149           An extension of XYBarRenderer that displays bars for different series values at the same x next 
150           to each other. The assumption here is that for each x (time or else) there is a y value for each 
151           series. If this is not the case, there will be spaces between bars for a given x.
152           This renderer does not include code to calculate the crosshair point for the plot.
153        **/    
154        public static final int ConstClusteredXYBarRenderer = 11;
155    
156        /**
157           Area item renderer for an XYPlot . This class can draw (a) shapes at each point, or (b) 
158           lines between points, or (c) both shapes and lines, or (d) filled areas, or (e) filled areas and shapes.
159        **/    
160        public static final int ConstXYAreaRenderer = 12;
161    
162        /** 
163            Area item renderer for an XYPlot .
164        **/    
165        public static final int ConstXYAreaRenderer2 = 13;
166    
167        /**
168           Line/Step item renderer for an XYPlot . This class draws lines between data points, only allowing horizontal or 
169           vertical lines (steps).
170        **/    
171        public static final int ConstXYStepRenderer = 14;
172    
173        /**
174           A step chart renderer that fills the area between the step and the x-axis.
175        **/             
176        public static final int ConstXYStepAreaRenderer = 15;
177            
178        /** Indicate if the Configuration Menu is visible **/
179        private boolean _ConfMenuIsOpened = false;
180    
181        /** Configuration Menu Window **/
182        private final JFrame _frameConfiguration = new JFrame("[=] Configuration Menu [=]");
183    
184        /**
185         * Display Usage when running the main.
186         *
187         */        
188        public static void usage () 
189        {
190            System.out.println("\nUSAGE : < NbGraphs (integer) > < Title (string) >");
191            System.out.println("\nwith <NbGraphs> : Graphs number (One Graph may contains several plots)");
192            System.out.println("     <Title>    : Main title");
193        }
194            
195        /**
196         * Constructor
197         *
198         * @param nbSubplots : subplots Number (ie Graphs number per plot)
199         * @param title : Main title to display
200         */        
201        public JQuickPlot(final int nbSubplots, final String title) {
202            
203            super(title);
204            
205            _nbSubplots = nbSubplots;
206            _labelX = new String[1];        
207            _labelX[0]="X";
208            _labelY = new String[_nbSubplots];
209            datasetColumnListX = new ColumnList[_nbSubplots];
210            datasetColumnListY = new ColumnList[_nbSubplots];
211            _subplotList = new XYPlot[_nbPlots][_nbSubplots];
212            _datasetFile = new String[_nbSubplots];
213    
214            for (int i = 0; i < _nbSubplots; i++)
215                {
216                    datasetColumnListX[i] = new ColumnList();
217                    datasetColumnListY[i] = new ColumnList();
218                    _datasetFile[i] = "";
219                    _labelY[i] = new String();
220                }
221    
222            initConfMenu();
223            
224            this._datasets = new XYSeriesCollection[_nbSubplots];
225    
226            for (int i = 0; i < _nbSubplots; i++) 
227                {           
228                    this._datasets[i] = new XYSeriesCollection();
229                }
230    
231            final JPanel content = new JPanel(new BorderLayout());          
232            JTabbedPane onglets = new JTabbedPane(SwingConstants.TOP);
233    
234            _plotList = new CombinedDomainXYPlot[_nbPlots];
235    
236            for(int i = 0; i< _nbPlots; i++)
237                {
238                    CombinedDomainXYPlot plot = createPlot(i);      
239                    final JFreeChart chart = new JFreeChart(title, plot);
240                    chart.setBorderPaint(Color.black);
241                    chart.setBorderVisible(true);
242                    chart.setBackgroundPaint(Color.white);
243                
244                    final ChartPanel chartPanel = new ChartPanel(chart);
245                    chartPanel.setPreferredSize(new java.awt.Dimension(500, 470));
246                    chartPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
247                    
248                    if(i==ConstDefaultXYItemRenderer)
249                        {
250                            onglets.add("Standard2",chartPanel) ;
251                        }                   
252                    else if(i==ConstXYLine3DRenderer)
253                        {
254                            onglets.add("Line3D",chartPanel) ;
255                        }
256                    else if(i==ConstXYSplineRenderer)
257                        {
258                            onglets.add("Spline",chartPanel) ;
259                        }
260                    else if(i==ConstYIntervalRenderer)
261                        {
262                            onglets.add("YInterval",chartPanel) ;
263                        }
264                    else if(i==ConstXYDifferenceRenderer)
265                        {
266                            onglets.add("Difference",chartPanel) ;
267                        }
268                    else if(i==ConstXYDotRenderer)
269                        {
270                            onglets.add("Dot",chartPanel) ;
271                        }
272                    else if(i==ConstXYErrorRenderer)
273                        {
274                            onglets.add("Error",chartPanel) ;
275                        }
276                    else if(i==ConstVectorRenderer)
277                        {
278                            onglets.add("Vector",chartPanel) ;
279                        }
280                    else if(i==ConstDeviationRenderer)
281                        {
282                            onglets.add("Deviation",chartPanel) ;
283                        }
284                    else if(i==ConstCyclicXYItemRenderer)
285                        {
286                            onglets.add("Cyclic",chartPanel) ;
287                        }
288                    else if(i==ConstClusteredXYBarRenderer)
289                        {
290                            onglets.add("ClusteredBar",chartPanel) ;
291                        }
292                    else if(i==ConstXYAreaRenderer)
293                        {
294                            onglets.add("Area",chartPanel) ;
295                        }
296                    else if(i==ConstXYAreaRenderer2)
297                        {
298                            onglets.add("Area2",chartPanel) ;
299                        }
300                    else if(i==ConstXYStepRenderer)
301                        {
302                            onglets.add("Step",chartPanel) ;
303                        }
304                    else if(i==ConstXYStepAreaRenderer)
305                        {
306                            onglets.add("StepArea",chartPanel) ;
307                        }
308                    else
309                        {
310                            onglets.add("Standard",chartPanel) ;
311                        }
312                    
313                    _plotList[i] = plot;
314                }
315            
316            content.add(onglets, BorderLayout.NORTH);
317    
318    
319            final JPanel buttonPanel1 = new JPanel(new FlowLayout());
320            
321            for (int i = 0; i < _nbSubplots; i++) {
322                final JButton buttonRun = new JButton("Run " + i);
323                buttonRun.setActionCommand("RUN" + i);
324                buttonRun.addActionListener(this);
325                buttonPanel1.add(buttonRun);
326            }
327    
328            final JButton buttonRunAll = new JButton("Run All ");
329            buttonRunAll.setActionCommand("RUNALL");
330            buttonRunAll.addActionListener(this);
331            buttonPanel1.add(buttonRunAll);
332            
333            final JButton buttonConf = new JButton("Conf");
334            buttonConf.setActionCommand("CONF");
335            buttonConf.addActionListener(this);
336            buttonPanel1.add(buttonConf);
337            
338            content.add(buttonPanel1, BorderLayout.CENTER);
339    
340            final JPanel buttonPanel2 = new JPanel(new FlowLayout());
341            
342            for (int i = 0; i < _nbSubplots; i++) {
343                final JButton buttonClear = new JButton("clear " + i);
344                buttonClear.setActionCommand("CLEAR" + i);
345                buttonClear.addActionListener(this);
346                buttonPanel2.add(buttonClear);
347            }
348    
349            final JButton buttonClearAll = new JButton("Clear All ");
350            buttonClearAll.setActionCommand("CLEARALL");
351            buttonClearAll.addActionListener(this);
352            buttonPanel2.add(buttonClearAll);
353            
354            final JButton buttonExit = new JButton("Exit");
355            buttonExit.setActionCommand("EXIT");
356            buttonExit.addActionListener(this);
357            buttonPanel2.add(buttonExit);
358            
359            content.add(buttonPanel2, BorderLayout.SOUTH);
360    
361            setContentPane(content);
362        }
363        
364    
365        /**
366         * Initialyze the Configuration Menu
367         *     
368         */            
369        private void initConfMenu()
370        {
371            JFrame.setDefaultLookAndFeelDecorated(true);
372                    
373            _frameConfiguration.getContentPane().setLayout(new BoxLayout(_frameConfiguration.getContentPane(), BoxLayout.X_AXIS));          
374            _frameConfiguration.getContentPane().add(new MainConfiguration("Main Config ",_labelX));
375                    
376            for (int i=0; i < _nbSubplots; i++)
377                {           
378                    JFrame mainFrame = new JFrame("plotConfiguration");
379                    _frameConfiguration.getContentPane().add(new PlotConfiguration("Config ",i, datasetColumnListX, datasetColumnListY, _datasetFile, _labelY));   
380                }
381            
382            _ConfMenuIsOpened = false;
383            _frameConfiguration.setVisible(false);  
384            _frameConfiguration.pack();
385        }
386    
387    
388        /**
389         * Display/hide the Configuration Menu
390         *
391         */        
392        private void showConfMenu()
393        {
394            if(!_ConfMenuIsOpened)
395                {   
396                    _frameConfiguration.setVisible(true);                   
397                    _ConfMenuIsOpened = true;
398                }
399            
400            else
401                {
402                    _ConfMenuIsOpened = false;
403                    _frameConfiguration.setVisible(false);  
404                }
405        }
406        
407        
408        /**
409         * Plot Creation with _nbSuplots
410         *
411         * @param subPlotType : subplotType for renderer
412         */        
413        private CombinedDomainXYPlot createPlot(int subPlotType)
414        {
415            final CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("X"));
416            
417            for (int i = 0; i < _nbSubplots; i++) {
418    
419                final NumberAxis rangeAxis = new NumberAxis("Y" + i);
420                final XYPlot subplot;
421    
422                if(subPlotType == ConstDefaultXYItemRenderer)
423                    {
424                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new DefaultXYItemRenderer());
425                        /*
426                          default renderer for the XYPlot class. This is an alias for the XYLineAndShapeRenderer class.
427                        */
428                    }
429                
430                else if(subPlotType == ConstXYLine3DRenderer)
431                    {
432                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new XYLine3DRenderer());
433                        /*
434                          A XYLineAndShapeRenderer that adds a shadow line to the graph to emulate a 3D-effect.
435                        */
436                    }
437        
438                else if(subPlotType == ConstXYSplineRenderer)
439                    {
440                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new XYSplineRenderer());                               
441                    }
442                
443                else if(subPlotType == ConstYIntervalRenderer)
444                    {
445                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new YIntervalRenderer());
446                        /*
447                          A renderer that draws a line connecting the start and end Y values for an XYPlot .
448                        */
449                    }
450    
451                else if(subPlotType == ConstXYDifferenceRenderer)
452                    {
453                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new XYDifferenceRenderer());
454                        /*
455                          A renderer for an XYPlot that highlights the differences between two series. The renderer expects a dataset that:
456                          - has exactly two series;
457                          - each series has the same x-values;
458                          - no null values; 
459                        */
460                    }
461    
462                else if(subPlotType == ConstXYDotRenderer)
463                    {
464                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new XYDotRenderer());
465                        /*
466                          A renderer that draws a small dot at each data point for an XYPlot .
467                        */
468                    }
469    
470                else if(subPlotType == ConstXYErrorRenderer)
471                    {
472                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new XYErrorRenderer());
473                        
474                    }
475    
476                else if(subPlotType == ConstVectorRenderer)
477                    {
478                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new VectorRenderer());
479                        
480                    }
481    
482                else if(subPlotType == ConstDeviationRenderer)
483                    {
484                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new DeviationRenderer());
485                    }
486    
487                else if(subPlotType == ConstCyclicXYItemRenderer)
488                    {
489                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new CyclicXYItemRenderer());
490                        /*
491                          The Cyclic XY item renderer is specially designed to handle cyclic axis. While the standard renderer would
492                          draw a line across the plot when a cycling occurs, the cyclic renderer splits the line at each cycle end instead.
493                          This is done by interpolating new points at cycle boundary. Thus, correct appearance is restored. 
494                          The Cyclic XY item renderer works exactly like a standard XY item renderer with non-cyclic axis.
495                        */
496                    }
497    
498                else if(subPlotType == ConstClusteredXYBarRenderer)
499                    {
500                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new ClusteredXYBarRenderer());
501                        /*
502                          An extension of XYBarRenderer that displays bars for different series values at the same x next 
503                          to each other. The assumption here is that for each x (time or else) there is a y value for each 
504                          series. If this is not the case, there will be spaces between bars for a given x.
505                          This renderer does not include code to calculate the crosshair point for the plot.
506                        */
507                    }
508    
509                else if(subPlotType == ConstXYAreaRenderer)
510                    {
511                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new XYAreaRenderer());
512                        /*
513                          Area item renderer for an XYPlot . This class can draw (a) shapes at each point, or (b) 
514                          lines between points, or (c) both shapes and lines, or (d) filled areas, or (e) filled areas and shapes.
515                        */
516                    }
517    
518                else if(subPlotType == ConstXYAreaRenderer2)
519                    {
520                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new XYAreaRenderer2());
521                        /* 
522                           Area item renderer for an XYPlot .
523                        */
524                    }
525    
526                else if(subPlotType == ConstXYStepRenderer)
527                    {
528                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new XYStepRenderer());
529                        /*
530                          Line/Step item renderer for an XYPlot . This class draws lines between data points, only allowing horizontal or 
531                          vertical lines (steps).
532                        */
533                    }
534              
535                else if(subPlotType == ConstXYStepAreaRenderer)
536                    {
537                        subplot = new XYPlot(this._datasets[i],  null, rangeAxis , new XYStepAreaRenderer());
538                        /*
539                          A step chart renderer that fills the area between the step and the x-axis.
540                        */              
541                    }         
542               
543                else
544                    {
545                        subplot = new XYPlot(this._datasets[i], null, rangeAxis, new StandardXYItemRenderer());
546                        /*
547                          Standard item renderer
548                        */
549                    }               
550    
551                _subplotList[subPlotType][i] = subplot;
552                
553                subplot.setBackgroundPaint(Color.lightGray);
554                subplot.setDomainGridlinePaint(Color.white);
555                subplot.setRangeGridlinePaint(Color.white);
556              
557                plot.setBackgroundPaint(Color.lightGray);
558                plot.setDomainGridlinePaint(Color.white);
559                plot.setRangeGridlinePaint(Color.white);
560                final ValueAxis axis = plot.getDomainAxis();
561                axis.setAutoRange(true);
562     
563                plot.add(subplot);      
564            }
565    
566            return plot;
567        }
568    
569       
570        /**
571         * Handles a click on the Conf/Exit/Clear/Clear All/Run/Run All buttons.
572         *
573         * @param e  the action event.
574         */
575        public void actionPerformed(final ActionEvent e) {
576            
577            if (e.getActionCommand().equals("CONF")) 
578                {           
579                    showConfMenu();     
580                }
581    
582            else if (e.getActionCommand().equals("EXIT")) 
583                {
584                    System.exit(0);
585                }
586    
587            else if (e.getActionCommand().equals("CLEARALL")) 
588                {
589                    for (int i = 0; i < _nbSubplots; i++) 
590                        {                                           
591                            this._datasets[i].removeAllSeries();
592                            for(int j = 0; j < _nbPlots; j++)
593                                {
594                                    _subplotList[j][i].getRangeAxis().setLabel("Y" + i);
595                                }
596                        }
597    
598                    for(int i =0; i< _nbPlots; i++)
599                        {
600                            _plotList[i].getDomainAxis().setLabel("X");
601                        }                   
602                }
603    
604            else if (e.getActionCommand().startsWith("CLEAR")) 
605                {
606                    int plotNum = Integer.valueOf(e.getActionCommand().substring(5)).intValue();
607                    this._datasets[plotNum].removeAllSeries();
608                    for(int i = 0; i < _nbPlots; i++)
609                        {
610                            _subplotList[i][plotNum].getRangeAxis().setLabel("Y" + plotNum);
611                        }                           
612                }
613    
614            else if (e.getActionCommand().equals("RUNALL")) 
615                {
616            
617                    if(!_labelX[0].trim().equals(""))
618                        {
619                            for(int i =0; i< _nbPlots; i++)
620                                {
621                                    _plotList[i].getDomainAxis().setLabel(_labelX[0]);
622                                }
623                        }
624                    else
625                        {
626                            for(int i =0; i< _nbPlots; i++)
627                                {
628                                    _plotList[i].getDomainAxis().setLabel("X");
629                                }                   
630                        }
631    
632                    for (int i = 0; i < _nbSubplots; i++) 
633                        {                   
634                            if(!_labelY[i].trim().equals(""))
635                                {
636                                    for(int k = 0; k < _nbPlots; k++)
637                                        {
638                                            _subplotList[k][i].getRangeAxis().setLabel(_labelY[i]);
639                                        }
640                                }
641                            
642                            else 
643                                {
644                                    for(int k = 0; k < _nbPlots; k++)
645                                        {
646                                            _subplotList[k][i].getRangeAxis().setLabel("Y" + i);
647                                        }
648    
649                                }
650                            
651                            this._datasets[i].removeAllSeries();                    
652                            if(!_datasetFile[i].equals(""))
653                                {
654                                    this._datasets[i].removeAllSeries();
655                                    int colX = datasetColumnListX[i].get(0).getColumn();
656                            
657                                    for(int j= 0; j < datasetColumnListY[i].size(); j++)
658                                        {
659                                            int colY = datasetColumnListY[i].get(j).getColumn();
660                                            final XYSeries serie;
661                                            String strSerie = "";
662                                            
663                                            if (!datasetColumnListY[i].get(j).isTitleEmpty())
664                                                {
665                                                    strSerie = datasetColumnListY[i].get(j).getTitle();
666                                                    serie = new XYSeries(strSerie);
667                                                    this._datasets[i].addSeries(serie);                                     
668                                                }
669                                            
670                                            else
671                                                {
672                                                    strSerie = String.valueOf(i) + "." + String.valueOf(j);
673                                                    serie = new XYSeries(strSerie);
674                                                    this._datasets[i].addSeries(serie);                             
675                                                }
676    
677                                                                                                            
678                                            // Read the Text File   
679                                            try{
680                                                InputStream ips=new FileInputStream(_datasetFile[i]); 
681                                                InputStreamReader ipsr=new InputStreamReader(ips);
682                                                BufferedReader br=new BufferedReader(ipsr);
683                                                String ligne;
684                                                String [] content;
685    
686                                                while ((ligne=br.readLine())!=null)
687                                                    {
688                                                        if(!ligne.trim().equals(""))
689                                                            {
690                                                                content = ligne.split("\\s+");                  
691                                                                if(((content.length < colX +1) || (content.length < colY +1)) && (content.length > 0)) 
692                                                                    {
693                                                                        System.out.println("Error : Bad column definition for <" + _datasetFile[i] + "> in Plots Group Config " + i + " or invalid line in the File");  
694                                                                    }
695                                                                else
696                                                                    {                                                       
697                                                                        this._datasets[i].getSeries(strSerie).add(Float.valueOf(content[colX]),Float.valueOf(content[colY]));                                       
698                                                                    }
699                                                            }
700                                                    }
701                                                ips.close();
702                                            }                                                       
703                                            catch (Exception ex){
704                                                System.out.println("Error : Cannot Read File <" + _datasetFile[i] + "> needed for Plots Group " + i);   
705                                            }
706                                        }
707                                }
708                        }          
709                }
710            
711            else if (e.getActionCommand().startsWith("RUN")) 
712                {    
713                    int plotNum = Integer.valueOf(e.getActionCommand().substring(3)).intValue();
714    
715                    if(!_labelX[0].trim().equals(""))
716                        {                   
717                            for(int i =0; i< _nbPlots; i++)
718                                {
719                                    _plotList[i].getDomainAxis().setLabel(_labelX[0]);
720                                }
721                        }
722    
723                    
724                    if(!_labelY[plotNum].trim().equals(""))
725                        {
726                            for(int j = 0; j < _nbPlots; j++)
727                                {
728                                    _subplotList[j][plotNum].getRangeAxis().setLabel(_labelY[plotNum]);
729                                }
730                        }
731    
732                    else
733                        {
734                            for(int j = 0; j < _nbPlots; j++)
735                                {
736                                    _subplotList[j][plotNum].getRangeAxis().setLabel("Y" + plotNum);
737                                }
738    
739                        }
740                            
741    
742                    if(!_datasetFile[plotNum].equals(""))
743                        {                   
744                            this._datasets[plotNum].removeAllSeries();
745    
746                            int colX = datasetColumnListX[plotNum].get(0).getColumn();
747    
748                            for(int i= 0; i < datasetColumnListY[plotNum].size(); i++)
749                                {
750                                    int colY = datasetColumnListY[plotNum].get(i).getColumn();
751    
752                                    final XYSeries serie;
753                                    String strSerie = "";
754    
755                                    if (!datasetColumnListY[plotNum].get(i).isTitleEmpty())
756                                        {
757                                            strSerie = datasetColumnListY[plotNum].get(i).getTitle();
758                                            serie = new XYSeries(strSerie);
759                                            this._datasets[plotNum].addSeries(serie);                                       
760                                        }
761    
762                                    else
763                                        {
764                                            strSerie = String.valueOf(plotNum) + "." + String.valueOf(i);
765                                            serie = new XYSeries(strSerie);
766                                            this._datasets[plotNum].addSeries(serie);                               
767                                        }
768    
769                                                                    
770                                    // Read the Text File   
771                                    try{
772                                        InputStream ips=new FileInputStream(_datasetFile[plotNum]); 
773                                        InputStreamReader ipsr=new InputStreamReader(ips);
774                                        BufferedReader br=new BufferedReader(ipsr);
775                                        String ligne;
776                                        String [] content;
777    
778                                        while ((ligne=br.readLine())!=null){
779                                            if(!ligne.trim().equals(""))
780                                                {
781                                                    content = ligne.split("\\s+");              
782                                                    if(((content.length < colX +1) || (content.length < colY +1)) && (content.length > 0)) 
783                                                        {
784                                                            System.out.println("Error : Bad column definition for <" + _datasetFile[plotNum] + "> in Plots Group Config " + plotNum + " or invalid line in the File");  
785                                                        }
786                                                    else
787                                                        {
788                                                            this._datasets[plotNum].getSeries(strSerie).add(Float.valueOf(content[colX]),Float.valueOf(content[colY]));                                     
789                                                        }
790                                                }
791                                        }
792                                        ips.close();
793                                    }               
794                                    catch (Exception ex){
795                                        System.out.println("Error : Cannot Read File <" + _datasetFile[plotNum] + "> needed for Plots Group " + plotNum);  
796                                    }
797                                }
798                        }
799    
800                    else
801                        {                   
802                            System.out.println("Error : No File defined for Plots Group " + plotNum);  
803                        }
804                }
805        }
806    
807    
808        /**
809         * Starting point for JQuickPlot.
810         *
811         * @param  args <br/>
812         * args[0] - NbGraphs (integer) : Graphs number (One Graph may contains several plots) <br/>
813         * args[1] - Title (String)) : Main title
814         */
815        public static void main(final String[] args) 
816        {
817            if (args.length == 2)
818                {
819                    try
820                        {
821                            final JQuickPlot startJQuickPlot = new JQuickPlot(Integer.valueOf(args[0]).intValue(),args[1]);
822                            startJQuickPlot.pack();
823                            RefineryUtilities.centerFrameOnScreen(startJQuickPlot);        
824                            startJQuickPlot.setVisible(true);
825                        }
826                    
827                    catch (Exception ex){
828                        JQuickPlot.usage();
829                    }
830                }
831    
832            else
833                JQuickPlot.usage();
834    
835        }
836    
837    
838    }