1

I'm making a simple sorting benchmark in Java Swing and I want it to display a graph that changes with time. But the graph is not updating when the algorithm runs. I'm really confused. Can someone please explain what I'm doing wrong?

The array is filled with random data when the GUI is running

int A[]=null;int [] copyOfA=null; 

chart

   final XYSeriesCollection dataset = new XYSeriesCollection();
   private ChartPanel createDemoPanel() {  
       JFreeChart jfreechart = ChartFactory.createXYLineChart(title, "array", "time",dataset ,
            PlotOrientation.VERTICAL, true, true, false);
    jfreechart.setBackgroundPaint(Color.white);
    XYPlot plot = (XYPlot) jfreechart.getPlot();
    plot.getDomainAxis().setRange(0, 1000); //array
    plot.getRangeAxis().setRange(-1,1);//time

    //plot.getDomainAxis().setFixedAutoRange(20);
    //plot.getRangeAxis().setFixedAutoRange(100);
    // render shapes and lines
    XYLineAndShapeRenderer renderer =
        new XYLineAndShapeRenderer(true, true);
    plot.setRenderer(renderer);
    renderer.setBaseShapesVisible(true);
    renderer.setBaseShapesFilled(true);

    return new ChartPanel(jfreechart);
}

inside ActionPerformed

   private void insSortActionPerformed(java.awt.event.ActionEvent evt) {       
   XYSeries series = new XYSeries("ins sort");

    if( insSort.isEnabled()) {

   long startTime = System.currentTimeMillis();
   insSort(A);
   long endTime = System.currentTimeMillis();
   totalRuntime += (endTime - startTime);
                             }

    series.add(totalRuntime,A.length);
    dataset.addSeries(series);                                         
     }
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user46000
  • 77
  • 6
  • Is `insortA(A)` the method responsible to do the sort? If so then your graphic will be updated just once when this method is done. If this method takes too long then your GUI will freeze since it will block the [Event Dispatch Thread](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html) until finishes its execution. – dic19 Jan 14 '14 at 00:41
  • unfortunately nothing appears on screen.. – user46000 Jan 14 '14 at 00:43
  • i can't find a way to fix it, any suggestions ? – user46000 Jan 14 '14 at 00:47
  • Try setting the renderers' series paint: `renderer.setSeriesPaint(0, Color.BLACK);`. Not sure which is the default paint, maybe `null` or `Color.WHITE`. – dic19 Jan 14 '14 at 00:50
  • that's what i'm getting.IMG]http://i44.tinypic.com/2ry0axv.jpg[/IMG] – user46000 Jan 14 '14 at 00:56
  • Well the Y axis range is set to (-1,1) but `totalRuntime` is probably getting a value near to 1000 (1 second). So you won't see the point that is drawn. Check for the domain axis as well, how many elements does the array have? If its > 1000 then you won't see the point either. – dic19 Jan 14 '14 at 01:00
  • thankss for your help, but the problem is that no "series" line appears in the window. It should be like this [IMG]i44.tinypic.com/29o3mur.png[/IMG] – user46000 Jan 14 '14 at 01:22
  • For [example](http://stackoverflow.com/a/13205322/230513). – trashgod Jan 14 '14 at 01:59
  • Could you explain me how can I use swingworker in my program ? Your help will be greatly appreciated. – user46000 Jan 14 '14 at 02:14

1 Answers1

0

At this line the Y axis range is set to (-1,1) interval:

plot.getDomainAxis().setRange(0, 1000); //array
plot.getRangeAxis().setRange(-1,1);//time

But Y axis is intended to take the value from totalRuntime which is a time difference given in millis:

if( insSort.isEnabled()) {
   long startTime = System.currentTimeMillis();
   insSort(A);
   long endTime = System.currentTimeMillis();
   totalRuntime += (endTime - startTime); // this is certainly > 1
}
series.add(totalRuntime,A.length);
dataset.addSeries(series); 

This value will be certainly > 1 (unless you have the most powerful computer ever :). So you can see which value is getting totalRuntime and adjust the Y axis range accordingly.

You might also check:

  • Domain axis range: if the array has more than 1000 elements then you won't see the graphic either.
  • Is insSort.isEnabled() actually true? If not so then you'll be adding garbage to dataset.

Addendum

I want to graph sorting time versus the number of elements

Well you can take a look to the example below. As I haven't the sort methods implementation the example emulates the times using Swing timer. The key is adding the values to the series properly and having the right ranges set.

Note: as times are random generated then the shown info is garbage. The example tries to illustrate the process you should follow to make the graphic work. Pay special attention to fillChart() method: it makes the trick.

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
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.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class Demo {

    private final XYSeries _timeSeries = new XYSeries("Time Series");
    boolean _shouldPaint;

    private void createAndShowGUI() {

        JToggleButton fillChart = new JToggleButton("Fill chart") ;
        fillChart.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JToggleButton toggleButton = (JToggleButton)e.getSource();
                if(toggleButton.isSelected()) {
                    _timeSeries.clear();
                    _shouldPaint = true;
                    fillChart();
                } else {
                    _shouldPaint = false;
                }
            }
        });

        JPanel content = new JPanel(new BorderLayout());
        content.add(getFreeChartPanel(), BorderLayout.CENTER);
        content.add(fillChart, BorderLayout.SOUTH);

        JFrame frame = new JFrame("Demo");      
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JPanel getFreeChartPanel() {
        String title = "Time series example";

        XYSeriesCollection dataset = new XYSeriesCollection();
        dataset.addSeries(_timeSeries); // series is added only once!

        JFreeChart chart = ChartFactory.createXYLineChart(title, "Array elements", "Time (in millis)", dataset, 
                                                         PlotOrientation.VERTICAL, true, true, false);       
        XYPlot plot = chart.getXYPlot();
        plot.setRenderer(new XYLineAndShapeRenderer(true, true));
        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(true);
        plot.getDomainAxis().setRange(0, 1000); // Number of elements - top visible: 1000
        plot.getRangeAxis().setRange(0, 4000); // Time employed to do the sort - top visible: 4 seconds (4k millis)        

        return new ChartPanel(chart);
    }

    /**
     * You should do your own implementation of this method.
     */
    private void fillChart() {
        Timer timer = new Timer(500, new ActionListener() {

            long lastTimeMillis = System.currentTimeMillis();
            int domainAxis = 0;

            @Override
            public void actionPerformed(ActionEvent e) {
                if(_shouldPaint) {
                    long currentTimeMillis = System.currentTimeMillis();
                    long rangeAxisValue = (long)((currentTimeMillis - lastTimeMillis) * Math.random());
                    int domainAxisValue = domainAxis + 100;

                    _timeSeries.add(domainAxisValue, rangeAxisValue);
                    // Note this is the unique line that has an effect on the graphic

                    lastTimeMillis = currentTimeMillis;
                    domainAxis = domainAxisValue;

                } else {
                    Timer timer = (Timer)e.getSource();
                    timer.stop();
                }
            }
        });

        timer.setDelay(1500);
        timer.start();
    }

    public static void main(String[] args) {   
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().createAndShowGUI();
            }
        });
    }    
}

Picture

enter image description here

dic19
  • 17,821
  • 6
  • 40
  • 69
  • thanks for your help, but the problem is that no "series" line appears in the window. It should be like this [IMG]i44.tinypic.com/29o3mur.png[/IMG] – user46000 Jan 14 '14 at 01:25
  • @user3136729 that picture shows a progression chart, where the range axis shows the given value for the same phenomenon in a given period of time. So what do you want to do? 1) Do you want graphic the time employed to sort the array (range) versus the number of elements (domain)? 2) The opposite: number of elements (range) versus time (domain)? – dic19 Jan 14 '14 at 12:54
  • yes I want to graph sorting time versus the number of elements. – user46000 Jan 14 '14 at 14:51
  • Can you give me an example how to do this with insertion sort? public void insSort(int[] a) { for (int j = 1; j < a.length; j++) { int comp = 0 ; int exchange = 0; int tmp = a[j]; int i = j - 1; while (i >= 0 && a[i] < tmp) { comp++; a[i + 1] = a[i]; exchange++; i--; } a[i + 1] = tmp; } } – user46000 Jan 14 '14 at 14:55
  • No, if you want I can give you an example about making the graphic work. The implementation of sort methods is online on hundreds of sites, just pick one. @user3136729 – dic19 Jan 14 '14 at 15:02
  • I really need your help. – user46000 Jan 14 '14 at 15:11
  • @user3136729 See updated answer. See `fillChart()` method. Note the only line that has a real effect on the graphic is when you add a new value to the series. Hope it be helpful :) – dic19 Jan 14 '14 at 15:29
  • It was a big help, thank you very much for your support. It worked ! – user46000 Jan 14 '14 at 16:56