使用JFreeChart更改系列时出现随机错误

ara*_*sql 6 java concurrency swing jfreechart

我正在制作一个显示背景计算结果的GUI.但在此之前,我想测试更改数据集.这是我的代码:

 DefaultXYDataset dataset = new DefaultXYDataset();
@Override
        public void run() {
                // TODO Auto-generated method stub
                for (int i = 0; i < periods; i++) {
                        series[0][i] = (double) i;
                        series[1][i] = 0;
                }
                dataset.addSeries("Series0", series);
                for (int it = 0; it < 10; it++) {
                        series[1][random.nextInt(periods)] =  random.nextInt(100) / 2;
                        double[][] d = new double[2][periods];
                        for (int i = 0; i < periods; i++) {
                                d[0][i] = series[0][i];
                                d[1][i] = series[1][i];
                        }
                        dataset.removeSeries("Series0");
                        dataset.addSeries("Series0", series);
//                      try {
//                              Thread.sleep(100);
//                      } catch (java.lang.InterruptedException ex) {
//                      }
                }
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我想改变图上的点(每次完成'一些复杂的计算') - 这个改变是在我在另一个类中调用的线程中.我的问题是这整个概念都不起作用.它抛出'系列索引超出边界'-IllegalArgumentException,'索引越界' - 某些库内部arraylist等.我没有使用DynamicTimeSeriesCollection,因为我需要X轴是我内部迭代的数量而不是时间期间,并且当"某些计算"不是每隔一段时间完成时也会更新.你能告诉我我做错了什么吗?或者有更好的方法来更新/刷新图表吗?

tra*_*god 9

您的代码段未正确同步; 您应该更新您的datasetprocess()的方法SwingWorker,如图所示这里.而不是a DateAxis,使用a NumberAxis,如图所示ChartFactory.createXYLineChart().

附录:所引用示例的这种变化描绘了工人在折线图上的进展.请注意,域和范围都createXYLineChart()使用NumberAxis.

在此输入图像描述

private XYSeriesCollection collection = new XYSeriesCollection();
private XYSeries series = new XYSeries("Result");
...
collection.addSeries(series);
JFreeChart chart = ChartFactory.createXYLineChart(
    "Newton's Method", "X", "Y", collection,
    PlotOrientation.VERTICAL, false, true, false);
XYPlot plot = (XYPlot) chart.getPlot();
plot.getRangeAxis().setRange(1.4, 1.51);
plot.getDomainAxis().setStandardTickUnits(
    NumberAxis.createIntegerTickUnits());
XYLineAndShapeRenderer renderer =
    (XYLineAndShapeRenderer) plot.getRenderer();
renderer.setSeriesShapesVisible(0, true);
this.add(new ChartPanel(chart), BorderLayout.CENTER);
...
private int n;
@Override
protected void process(List<Double> chunks) {
    for (double d : chunks) {
        label.setText(df.format(d));
        series.add(++n, d);
    }
}
Run Code Online (Sandbox Code Playgroud)