Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JFreeChart更改序列时出现随机错误_Java_Swing_Concurrency_Jfreechart - Fatal编程技术网

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

Java 使用JFreeChart更改序列时出现随机错误,java,swing,concurrency,jfreechart,Java,Swing,Concurrency,Jfreechart,我正在制作一个显示背景计算结果的GUI。但在此之前,我想测试更改数据集。这是我的密码: DefaultXYDataset dataset = new DefaultXYDataset(); @Override public void run() { // TODO Auto-generated method stub for (int i = 0; i < periods; i++) {

我正在制作一个显示背景计算结果的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) {
//                      }
                }
DefaultXYDataset数据集=新的DefaultXYDataset();
@凌驾
公开募捐{
//TODO自动生成的方法存根
for(int i=0;i

如您所见,我想更改图形上的点(每次它完成“一些复杂的计算”)-此更改发生在我在另一个类中调用的线程中。我的问题是整个概念不起作用。它抛出了某些库内部arraylist的“Series index out bounds”-IllegalArgumentException,“index out bounds”-等。我没有使用DynamicMiseriesCollection,因为我需要X轴作为内部迭代的编号不是时间段,并且在“某些计算”完成时也会更新,不是每一个时间段。您能告诉我我做错了什么吗?或者有更好的方法更新/刷新图表吗?

您的代码段同步不正确;您应该从
过程()更新
数据集
的方法,如图所示。因为您的域是“我的内部迭代次数”,所以不要使用
日期轴
;而是使用
数字轴
,如图所示

附录:此变化将工人的进度绘制在折线图上。请注意,
createXYLineChart()
对域和范围使用
NumberAxis
。在折线图的数据集中给定一个
系列
,还请注意
过程()的实现
可以在新数据到达时安全地更新数据集;监听图表会相应地自我更新

private XYSeries series = new XYSeries("Result");
…
@Override
protected void process(List<Double> chunks) {
    for (double d : chunks) {
        label.setText(df.format(d));
        series.add(++n, d);
    }
}
private XYSeries=新XYSeries(“结果”);
…
@凌驾
受保护的无效进程(列表块){
for(双d:块){
label.setText(df.format(d));
系列。添加(++n,d);
}
}

导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.beans.PropertyChangeEvent;
导入java.text.DecimalFormat;
导入java.util.List;
导入javax.swing.JFrame;
导入javax.swing.JLabel;
导入javax.swing.JProgressBar;
导入javax.swing.SwingWorker;
导入org.jfree.chart.ChartFactory;
导入org.jfree.chart.ChartPanel;
导入org.jfree.chart.JFreeChart;
导入org.jfree.chart.axis.NumberAxis;
导入org.jfree.chart.plot.PlotOrientation;
导入org.jfree.chart.plot.XYPlot;
导入org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
导入org.jfree.data.xy.XYDataset;
导入org.jfree.data.xy.XYSeries;
导入org.jfree.data.xy.XYSeriesCollection;
/**
*@见https://stackoverflow.com/a/13205322/230513
*@见https://stackoverflow.com/questions/4637215
*/
公共期末班{
私有静态最终字符串S=“0.000000000000000”;
私有最终JProgressBar progressBar=新JProgressBar();
专用最终JLabel标签=新JLabel(S,JLabel.CENTER);
私有最终XYSeries=新XYSeries(“结果”);
私有最终XYDataset数据集=新的XYSeriesCollection(系列);
私有void create(){
JFrame f=新JFrame(“√2");
f、 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f、 添加(progressBar,BorderLayout.NORTH);
JFreeChart chart=ChartFactory.createXYLineChart(
“牛顿法”,“X”,“Y”,数据集,
PlotOrientation.VERTICAL,false,true,false);
XYPlot=(XYPlot)chart.getPlot();
plot.getRangeAxis().setRange(1.4,1.51);
plot.getDomainAxis().setStandardTickUnits(
NumberAxis.createIntegerTickUnits());
XylineandShaperEnder渲染器
=(XYLineAndShapeRenderer)plot.getRenderer();
renderer.SetSeriessShapesVisible(0,true);
f、 添加(新图表面板(图表){
@凌驾
公共维度getPreferredSize(){
返回新维度(640480);
}
},BorderLayout.CENTER);
f、 添加(标签,边界布局。南部);
f、 包装();
f、 setLocationRelativeTo(空);
f、 setVisible(真);
runCalc();
}
私有void runCalc(){
progressBar.SetUndeterminate(真);
TwoWorker任务=新TwoWorker();
task.addPropertyChangeListener((PropertyChangeEvent e)->{
如果(“progress”.equals(例如getPropertyName())){
progressBar.SetUndeterminate(假);
progressBar.setValue((整数)e.getNewValue());
}
});
task.execute();
}
私有类TwoWorker扩展SwingWorker{
专用静态最终整数N=5;
专用最终决策格式df=新决策格式;
双x=1;
私人int n;
@凌驾
受保护的Double doInBackground()引发异常{

对于(int i=1;我认为您需要在这里发布相关代码和您的问题。最好是尽可能接近A。我不确定这是否会改变什么,因为在我看来,问题在于我支持的代码
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.text.DecimalFormat;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * @see https://stackoverflow.com/a/13205322/230513
 * @see https://stackoverflow.com/questions/4637215
 */
public final class ChartWorker {

    private static final String S = "0.000000000000000";
    private final JProgressBar progressBar = new JProgressBar();
    private final JLabel label = new JLabel(S, JLabel.CENTER);
    private final XYSeries series = new XYSeries("Result");
    private final XYDataset dataset = new XYSeriesCollection(series);

    private void create() {
        JFrame f = new JFrame("√2");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(progressBar, BorderLayout.NORTH);
        JFreeChart chart = ChartFactory.createXYLineChart(
            "Newton's Method", "X", "Y", dataset,
            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);
        f.add(new ChartPanel(chart) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(640, 480);
            }
        }, BorderLayout.CENTER);
        f.add(label, BorderLayout.SOUTH);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
        runCalc();
    }

    private void runCalc() {
        progressBar.setIndeterminate(true);
        TwoWorker task = new TwoWorker();
        task.addPropertyChangeListener((PropertyChangeEvent e) -> {
            if ("progress".equals(e.getPropertyName())) {
                progressBar.setIndeterminate(false);
                progressBar.setValue((Integer) e.getNewValue());
            }
        });
        task.execute();
    }

    private class TwoWorker extends SwingWorker<Double, Double> {

        private static final int N = 5;
        private final DecimalFormat df = new DecimalFormat(S);
        double x = 1;
        private int n;

        @Override
        protected Double doInBackground() throws Exception {
            for (int i = 1; i <= N; i++) {
                x = x - (((x * x - 2) / (2 * x)));
                setProgress(i * (100 / N));
                publish(x);
                Thread.sleep(1000); // simulate latency
            }
            return x;
        }

        @Override
        protected void process(List<Double> chunks) {
            for (double d : chunks) {
                label.setText(df.format(d));
                series.add(++n, d);
            }
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new ChartWorker()::create);
    }
}