I seem to be having trouble getting my charts to update when I want them to do so. I know that when you add a dataseries to a chart it registers with that chart so that whenever the data is updated, the chart gets updated. But I have a weird problem with that. I've created my chart and my dataseries, and I have a loop like this:
But the chart doesn't update until it runs through the loop entirely. I have to wait until the loop is completed to see anything. I thought maybe my computer, being slow, was just not getting around to showing the chart until the loop was done anyway, so I tried making that '100' into '1000'. All that did was make it take 10x as long to show the chart.
So I thought I could trick it, by forcing it to update. I made my loop do this:
I thought that by creating a new chart and showing a new image I could force it to update, even if it was very slow. But it showed the exact same behavior, the chart wouldn't update until my loop was finished. I even tried creating an entirely new dataset each time through a loop, creating a new series, adding all my data to the series, adding the series to the dataset, plotting a new chart with that dataset, creating a new image from the chart, and then updating the jlabel with that image. This too showed the same behavior. Maybe I'm just a Java greenhorn, but it doesn't make much sense to me.
I'm wondering if this is a threading issue. Java GUIs get updated from a particular thread, the same one that event handlers run in (often called the EDT, the "event dispatch thread.") If all the code you've shown is running in an event handler, then by definition, the chart can't update until your code is through running, when that thread becomes free.
If you want live updates, then your loop has to run in a different thread; you could try something like
Thank you for the advice. I actually suspected that the issue might be a threading one, but that only seems to me to explain the problem with the first loop. In my second try, I had it creating a new chart and updating the jlabel in the same loop, which should then be in the same thread.
A different background thread is most definitely what you want, but what Ernest has not mentioned is that all code that modifies the GUI directly should be run in the EDT. You can use EventQueue.invokeLater for that. Or, if you're using Java 6, use SwingWorker with its doInBackground, publish, process and done methods:
- doInBackground runs your code in a different thread
- publish is called in this thread
- process is called on the EDT with one or more objects passed to a call to publish. These objects are cached in between calls, so don't expect one call of process to receive data that has been sent by the last call to publish only. You should check the entire List
- done is called on the EDT when doInBackground finishes
Thanks for your help! I created a thread for it and that ended up doing what I wanted it to do. I knew I'd have to use threading eventually for this project, but I thought I could test it without them first. It does make sense now.