使用Yahoo Finance Quotes时,jfreechart崩溃了
问题解决:解决方案正在改为JFreeChart v1.0.15
我有一个非常特殊的问题。
我设置的是一个文件,它向Yahoo Finance网站发送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中显示的代码来自该网站 ( RoyW发布的代码»2008年5月10日星期六上午7:52 )。
- 进入的数据量似乎不是问题,因为在请求1中,数据点多于请求2中的数据点
- 我下载数据的方式并不重要(我尝试直接从url读取,我尝试将
.csv
文件保存到文件夹,然后从文件夹中读取) - 问题不是随机发生的:我尝试多次启动JFrame(重新编译代码然后运行它),但“错误”引用每次都会崩溃JFrame。
额外的信息
可能与它有关的东西:
- 当我使用正确的引号启动图形并且我拖动图形时,会发生奇怪的事情。 在某个时间间隔,似乎每个周末,烛台变得越来越小,直到它们只是条纹。 然后,当我拖过周末时,它们会变得更厚,直到它们再次恢复正常。 这似乎发生在每个周末。 请参考以下图片:
所以它让我觉得它可能与交易日有关 。 但这也没有任何意义,因为2011年 1月1日(请求1)落在星期六和2012年 3月1日(请求2)落在星期四,而请求1成功,请求2失败。
对于我应该做什么,我完全不知道。
所有帮助非常感谢。
更新
根据要求,这里是带有trashgod建议的SSCCE(使用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 dataItems = new ArrayList(); 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("yMd"); 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解决了所有问题。 通过广泛回答并提及所使用的库版本,不知不觉地解决我的问题。
有谁知道如何帮助其他有同样问题的人? 是否有一个门户网站,我可以记下这个错误?
CandlestickDemo
适用于jfreechart v1.0.15和您的任何一个查询。 我做了两处改动:
-
在事件派发线程上构造GUI; 如果不这样做会导致数据竞争具有非确定性结果:
EventQueue.invokeLater(new Runnable() { @Override public void run() { new CandlestickDemo("GOOG").setVisible(true); } });
-
省略后备缓冲区,虽然它可能无关紧要:
ChartPanel chartPanel = new ChartPanel(chart, false);
-
附录:作为参考,它似乎调用
ParamChecks.nullNotPermitted()
在r2692中应用 ,取代了显式检查,但渲染器在其他方面没有变化。 -
附录:在v1.0.14下,该示例与
DateAxis
的DefaultTimeline
DateAxis
正常工作,后者在过渡期间发生了重大变化 。 -
附录:@David Gilbert指出相关的变化可能在r2465中找到。
- 使用getServletConfig()时获取NPE .getServletContext()。getAttribute()(Java)
- Spring Batch:org.springframework.batch.item.ReaderNotOpenException:Reader必须先打开才能读取
- 避免使用keycloak默认登录页面并使用项目登录页面
- C#和Java中的hex到字节数组给出了不同的结果
- 在Java VisualVM中看不到我自己的应用程序方法
- 从Java中的synchronized上下文调用Thread.sleep()
- 45000 ms后无法在端口7055上连接到主机127.0.0.1。 用FF版26.0和selenium独立jar2.39
- Java正则表达式替换基于操作系统的文件路径
- Spring Rest – exception生成Json数据