java - 使用雅虎财经报价时 jfreechart 崩溃

标签 java swing jfreechart yahoo-finance


问题已解决:解决方案正在更改为 JFreeChart v1.0.15


我有一个非常特殊的问题。

我设置的是一个文件,该文件向雅虎财经网站发送 url 请求,然后使用结果在 JFrame 中绘制 JFreeChart。

我无法理解的是以下内容:

对于某些 url 请求,JFrame 崩溃

它启动了,但只显示白屏。而对于其他请求,我的程序运行良好。

示例

例如:

此请求:

"http://ichart.yahoo.com/table.csv?s=GOOG&a=0&b=1&c=2011&d=6&e=24&f=2013&g=d&ignore=.csv";

工作正常。

但是这个请求:

"http://ichart.yahoo.com/table.csv?s=GOOG&a=2&b=1&c=2012&d=6&e=24&f=2013&g=d&ignore=.csv";

导致错误。

这怎么可能?

注意

我知道以下内容:

  • JFrame 崩溃了,但是 JVM 没有注意到它(没有注意到它崩溃了)
  • 在这两种情况下,股票报价(JFreeChart 使用的信息)的下载都很完美
  • 下载数据并在 JFreeChart 中显示的代码来自 this site (代码由 RoyW » 2008 年 5 月 10 日星期六上午 7:52 发布)。
  • 传入的数据量似乎不是问题,因为请求 1 中的数据点比请求 2 中的数据点多
  • 我下载数据的方式并不重要(我尝试直接从网址读取,并尝试将 .csv 文件保存到文件夹中,然后从该文件夹中读取)
  • 该问题不是随机发生的:我已尝试多次启动 JFrame(重新编译代码然后运行它),但“错误”引用每次都会导致 JFrame 崩溃。

额外信息

可能与之有关的事情:

  • 当我使用正确的报价启动图表并拖动图表时,会发生一些奇怪的事情。在一定的时间间隔内,似乎每个周末,烛台都会变得越来越小,直到只剩下一条条纹。然后当我拖过周末时,它们又变得更厚,直到再次变成正常尺寸。这似乎每个周末都会发生。引用以下图片:

enter image description here enter image description here enter image description here

所以这让我想到这可能与 trading days 有关。 。但这也没有任何意义,因为 1/1/2011(请求 1)恰逢星期六,而 3/1/2012(请求 2)恰逢星期六。星期四,请求 1 成功,请求 2 失败。

我完全不知道我应该做什么。

非常感谢所有帮助。

更新

根据要求,这里是 SSCCEtrashgod的建议(使用 JFreechart lib v1.0.14)。

    import org.jfree.chart.*;
    import org.jfree.chart.axis.*;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.chart.renderer.xy.CandlestickRenderer;
    import org.jfree.data.xy.*;

    import javax.swing.*;
    import java.awt.*;
    import java.io.*;
    import java.net.URL;
    import java.text.*;
    import java.util.*;
    import java.util.List;

    public class CandlestickDemo2 extends JFrame {
        public CandlestickDemo2(String stockSymbol) {
            super("CandlestickDemo");
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            DateAxis    domainAxis       = new DateAxis("Date");
            NumberAxis  rangeAxis        = new NumberAxis("Price");
            CandlestickRenderer renderer = new CandlestickRenderer();
            XYDataset   dataset          = getDataSet(stockSymbol);

            XYPlot mainPlot = new XYPlot(dataset, domainAxis, rangeAxis, renderer);

            //Do some setting up, see the API Doc
            renderer.setSeriesPaint(0, Color.BLACK);
            renderer.setDrawVolume(false);
            rangeAxis.setAutoRangeIncludesZero(false);
            domainAxis.setTimeline( SegmentedTimeline.newMondayThroughFridayTimeline() );

            //Now create the chart and chart panel
            JFreeChart chart = new JFreeChart(stockSymbol, null, mainPlot, false);
            ChartPanel chartPanel = new ChartPanel(chart, false);
            chartPanel.setPreferredSize(new Dimension(600, 300));

            this.add(chartPanel);
            this.pack();
        }
        protected AbstractXYDataset getDataSet(String stockSymbol) {
            //This is the dataset we are going to create
            DefaultOHLCDataset result = null;
            //This is the data needed for the dataset
            OHLCDataItem[] data;

            //This is where we go get the data, replace with your own data source
            data = getData(stockSymbol);

            //Create a dataset, an Open, High, Low, Close dataset
            result = new DefaultOHLCDataset(stockSymbol, data);

            return result;
        }
        //This method uses yahoo finance to get the OHLC data
        protected OHLCDataItem[] getData(String stockSymbol) {
            List<OHLCDataItem> dataItems = new ArrayList<OHLCDataItem>();
            try {
                String strUrl= "http://ichart.finance.yahoo.com/table.csv?s=GOOG&a=2&b=1&c=2012&d=6&e=24&f=2013&g=d&ignore=.csv";
                URL url = new URL(strUrl);
                BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
                DateFormat df = new SimpleDateFormat("y-M-d");

                String inputLine;
                in.readLine();
                while ((inputLine = in.readLine()) != null) {
                    StringTokenizer st = new StringTokenizer(inputLine, ",");

                    Date date       = df.parse( st.nextToken() );
                    double open     = Double.parseDouble( st.nextToken() );
                    double high     = Double.parseDouble( st.nextToken() );
                    double low      = Double.parseDouble( st.nextToken() );
                    double close    = Double.parseDouble( st.nextToken() );
                    double volume   = Double.parseDouble( st.nextToken() );
                    double adjClose = Double.parseDouble( st.nextToken() );

                    OHLCDataItem item = new OHLCDataItem(date, open, high, low, close, volume);
                    dataItems.add(item);
                }
                in.close();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            //Data from Yahoo is from newest to oldest. Reverse so it is oldest to newest
            Collections.reverse(dataItems);

            //Convert the list into an array
            OHLCDataItem[] data = dataItems.toArray(new OHLCDataItem[dataItems.size()]);

            return data;
        }

        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new CandlestickDemo2("GOOG").setVisible(true);
                }
            });
        }
    }

这会生成一个仅显示白屏的 JFrame。尝试将 strUrl 更改为

 "http://ichart.finance.yahoo.com/table.csv?s=GOOG&a=0&b=1&c=2011&d=6&e=24&f=2013&g=d&ignore=.csv";

你会发现它工作得很好。

更新

解决了!问题出在 JFreeChart 版本上。从 v1.0.14 更改为 v1.0.15 解决了一切。感谢trashgod通过广泛回答并提及所使用的库版本(不知不觉地)解决了我的问题。

有人知道我可以如何帮助其他遇到同样问题的人吗?有没有一个门户可以让我记下这个错误?

最佳答案

CandlestickDemo为我工作 v1.0.15 和您的任何一个查询。我做了两处更改:

  • event dispatch thread 上构建 GUI ;如果不这样做会导致数据竞争,并产生不确定的结果:

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            new CandlestickDemo("GOOG").setVisible(true);
        }
    });
    
  • 省略后备缓冲区,尽管它可能不相关:

    ChartPanel chartPanel = new ChartPanel(chart, false);
    
  • 附录:仅供引用,对 ParamChecks.nullNotPermission() 的调用似乎是 appliedr2692 ,替换显式检查,但渲染器在其他方面保持不变。

  • 附录:在 v1.0.14 下,该示例可以在 DateAxisDefaultTimeline 下正常运行。 ,其中changed substantially在此期间。

  • 附录:@David Gilbert 指出相关更改可在 r2465 中找到。 .

image

关于java - 使用雅虎财经报价时 jfreechart 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18413534/

相关文章:

java - 单击折线图上的点时获取值

java - JFreeChart:X 轴包含时间戳

java - 给定指向该节点的指针,删除链表的最后一个节点

java - Realm :迭代 RealmObject 并清除 ArrayList 字段

java - 一个Swing新手,想做一个小动眼的Java GUI实践但是卡住了

Java 使用客户端套接字的多线程

java - 无法使用 apache common io 中的比较器解析方法排序

java - 如何修改 JComponent 的 setBounds 方法?

java - 为什么 SwingWorker 会意外停止?

java - JFreeChart - 如何在 TimeSeries 图表的 X 轴上实时显示并保存数据