2

I'm trying to make a JFreeChart to compare the problem size of a tested method to its running time.

Here is the class that makes the scatter plot:

public class TestScatterPlot extends JFrame {
    public TestScatterPlot(String title, XYSeriesCollection dataset){
        super(title);
        JFreeChart chart = ChartFactory.createScatterPlot(
                "Time to problem size",
                "problem size",
                "time",
                dataset);
        XYPlot plot = (XYPlot)chart.getPlot();
        plot.setBackgroundPaint(new Color(255,228,196));


        // Create Panel
        ChartPanel panel = new ChartPanel(chart);
        setContentPane(panel);
    }
}

Here is the test method:

   @Test
   public void testHierholzersAlgorithm() {
        Map<Integer,Long> timeToProblemSize = new HashMap<>();
        for(int trial = 0;trial<1000;trial++) {
            //generate the test data
            long startTime = System.nanoTime();
            //run the method
            long runTime = System.nanoTime() - startTime;
            int dataSize = dataSize();
            //test the data
            timeToProblemSize.put(dataSize,runTime);


        }
        XYSeriesCollection dataset = new XYSeriesCollection();
        XYSeries series = new XYSeries("TimeToProblemSize");
        for(Integer probSize:timeToProblemSize.keySet()){
            series.add(probSize,timeToProblemSize.get(probSize));
        }
        dataset.addSeries(series);
        SwingUtilities.invokeLater(() -> {
            TestScatterPlot example = new TestScatterPlot("",dataset);
            example.setSize(800, 400);
            example.setLocationRelativeTo(null);
            example.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            example.setVisible(true);
        });
    }

When I run this, the chart frame seems to begin to appear then closes immediately.

How do I get my chart to show?

Note:

This is not a repeat of this question because the questioner is using a scanner reading user input. There is no scanner in this test method; all the input is generated randomly.

It is not a repeat of this question either. The questioner there had a Thread.sleep happening. There is no Thread.sleep here.

jimboweb
  • 4,362
  • 3
  • 22
  • 45
  • is this unit test? – miskender Feb 20 '18 at 17:07
  • Could you add your main-method to your question? – Ben Feb 20 '18 at 17:08
  • yes. it's a unit test – jimboweb Feb 20 '18 at 17:08
  • Depending of how you are running your unit tests, behavior may change. Unit test can run in different jvms, and after test jvm process will be killed. – miskender Feb 20 '18 at 17:09
  • If it's a unit test, could it be that once that the frame is rendered the test finishes, and everything is cleaned up? What if you create a *traditional* desktop app? – npinti Feb 20 '18 at 17:13
  • FYI it's running in JUnit 4.12. – jimboweb Feb 20 '18 at 17:13
  • I guess I could just use a regular main method instead. – jimboweb Feb 20 '18 at 17:14
  • Based on the answer from @Ben it appears that invokeLater doesn't work in a test method. If anyone knows a way to make the frame show in the test method I'd appreciate it. If there's no way to do it I'll just do this using a regular console app with a main method instead and accept Ben's answer. – jimboweb Feb 20 '18 at 17:21

1 Answers1

2

I am assuming as you are running this as a unit test the test environment stops the test as soon as it reaches the end of your test method. The invokeLater will probably not have run yet at this point.

You can test this with a simple test such as:

void test()
    {
        SwingUtilities.invokeLater(() -> {
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                System.out.println("interrupt");
            }
            System.out.println("went through");
        });
    }

which will do exactly nothing as the Thread gets shut down before it can print the went through.

Ben
  • 1,665
  • 1
  • 11
  • 22
  • You're right; the invokeLater never happens; the test method ends and cleans everything up first. – jimboweb Feb 20 '18 at 17:22
  • Okay, it seems no one knows how to make the invokeLater work in a JUnit test so I'll just go ahead and do it in a main method. I'll accept this as an answer, and edit the question title and tags so other people who have the same issue can find the answer more easily. – jimboweb Feb 20 '18 at 21:55