Jframe not showing ContentPane

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
noriandir
Posts: 8
Joined: Fri Jul 20, 2012 10:34 am
antibot: No, of course not.

Jframe not showing ContentPane

Post by noriandir » Mon Sep 03, 2012 12:49 pm

I have a CandleChart that I want to be saved as a PNGFile.
In order to do so, I import data from a file, creating a DefaultOHLCDataset, as shown here: http://pastie.org/4655649

Code: Select all

package model;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;

import org.jfree.chart.axis.SegmentedTimeline;
import org.jfree.data.xy.DefaultOHLCDataset;
import org.jfree.data.xy.OHLCDataItem;

public class ProcessData {
	private YardCalendar _calendar;
	private SegmentedTimeline _timeline;
	private String _market;
	private String _alarm;
	private String _stockSymbol;
	private DefaultOHLCDataset _dataSet = null;

	public String getAlarm() {
		return _alarm;
	}

	public YardCalendar getCalendar() {
		return _calendar;
	}

	public SegmentedTimeline getTimeline() {
		return _timeline;
	}

	public DefaultOHLCDataset getDataSet() {
		if(_dataSet == null){
			//This is the data needed for the dataset
			OHLCDataItem[] data = getData(_market, _stockSymbol, _alarm);

			//Create a dataset, an Open, High, Low, Close dataset
			_dataSet = new DefaultOHLCDataset(_stockSymbol, data);
		}

		return _dataSet;
	}

	public ProcessData(String market, String alarm, String stockSymbol){
		_calendar = new YardCalendar(market, alarm);
		_timeline = new SegmentedTimeline(SegmentedTimeline.DAY_SEGMENT_SIZE, 7, 0);
		_market = market;
		_alarm = alarm;
		_stockSymbol = stockSymbol;
	}



	protected OHLCDataItem[] getData(String market, String stockSymbol, String alarmPath) {
		List<OHLCDataItem> dataItems = new ArrayList<OHLCDataItem>();
		try {			
			FileInputStream candleValues = new FileInputStream(alarmPath+"/GuiValue.txt");
			DataInputStream in = new DataInputStream(candleValues);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));

			String inputLine;
			br.readLine();

			int i = 0;
			YardDay calendarDay;
			Date date;
			SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
			while ((inputLine = br.readLine()) != null) {
				calendarDay = _calendar.getDay(i);

				//adds holidays and weekends to the candle exception list
				while(calendarDay.isHoliday() || calendarDay.isWeekend()){
					date = formatter.parse(calendarDay.getYear()+"/"+calendarDay.getMonth()+"/"+calendarDay.getDay());
					_timeline.addException(date);
					calendarDay = _calendar.getDay(++i);
				}

				if(calendarDay.isWorkDay()){
					StringTokenizer st = new StringTokenizer(inputLine, " ");
					NumberFormat nf = NumberFormat.getInstance(Locale.ITALIAN);
					double open     = nf.parse(st.nextToken()).doubleValue();
					double high     = nf.parse(st.nextToken()).doubleValue();
					double low      = nf.parse(st.nextToken()).doubleValue();
					double close    = nf.parse(st.nextToken()).doubleValue();
					double volume   = nf.parse(st.nextToken()).doubleValue();

					date = formatter.parse(calendarDay.getYear()+"/"+calendarDay.getMonth()+"/"+calendarDay.getDay());

					OHLCDataItem item = new OHLCDataItem(date, open, high, low, close, volume);
					dataItems.add(item);
					i++;
				}
			}
			in.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}

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

		return data;
	}
}
After, a Chart is created given the Dataset, and a custom timeline is created, that does not contain weekends or holidays. Shown here: http://pastie.org/4655656

Code: Select all

package model;

import java.awt.Color;
import java.awt.Font;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;
import java.util.StringTokenizer;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.SegmentedTimeline;
import org.jfree.chart.plot.IntervalMarker;
import org.jfree.chart.plot.Marker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.xy.DefaultOHLCDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.TextAnchor;

public class CandleChartModel extends AbstractModel{
	private JFreeChart _chart;

	public JFreeChart getChart() {
		return _chart;
	}

	public CandleChartModel(ProcessData data) {
		createChart(data);
	}
	
	public void setChart(ProcessData data){
		createChart(data);
		setChanged();
		//model Push - send counter as part of the message
		notifyObservers(_chart);
	}
	
	private void createChart(ProcessData data) {
		//Creates and imports the data into the calendar
		DateAxis    domainAxis       = new DateAxis("Date");
		NumberAxis  rangeAxis        = new NumberAxis("Price");
		CandlestickRenderer candleRenderer = new CandlestickRenderer();
		XYLineAndShapeRenderer lineRenderer = new XYLineAndShapeRenderer(true,false);
		DefaultOHLCDataset candleDataset = data.getDataSet();
		XYDataset linesDataSet = null;

		XYPlot mainPlot = new XYPlot();
		mainPlot.setRangeAxis(rangeAxis);
		mainPlot.setDomainAxis(domainAxis);
		mainPlot.setDataset(0, candleDataset);
		mainPlot.setRenderer(0, candleRenderer);
		
		
		//Do some setting up, see the API Doc
		candleRenderer.setSeriesPaint(0, Color.BLACK);
		candleRenderer.setDrawVolume(true);
		rangeAxis.setAutoRangeIncludesZero(false);
		lineRenderer.setPaint(Color.BLACK);
		
		
		//Cutting the extra space that is included in the DomainAxis by setting the range manually
		long start = data.getCalendar().getDay(0).getDate().getTime() - SegmentedTimeline.DAY_SEGMENT_SIZE;
		long end = data.getCalendar().getDay(data.getCalendar().size()-1).getDate().getTime() + SegmentedTimeline.DAY_SEGMENT_SIZE;
		
		domainAxis.setMinimumDate(new Date(start));
		domainAxis.setMaximumDate(new Date(end));
		
		
		//WARNING: Does not work with all charts.
		domainAxis.setTimeline(data.getTimeline());

		
		//Adds the color areas corresponding to the sub patterns found.
		linesDataSet = addAreas(mainPlot, data.getAlarm(), candleDataset);
		mainPlot.setDataset(1, linesDataSet);
		mainPlot.setRenderer(1, lineRenderer);

		//Now create the chart and chart panel
		String title = data.getAlarm().substring(data.getAlarm().lastIndexOf("/")+1);
		
		_chart = new JFreeChart(mainPlot);
		_chart.setTitle(new TextTitle(title, new Font("SansSerif", Font.BOLD, 12)));
		_chart.setAntiAlias(true);
		_chart.removeLegend();
	}

	private XYDataset addAreas(XYPlot plot, String alarmPath, DefaultOHLCDataset dataset){
		StringTokenizer st;
		XYSeriesCollection sets = new XYSeriesCollection();
		try {
			FileInputStream fs = new FileInputStream(alarmPath+"/Disegno.txt");
			DataInputStream in = new DataInputStream(fs);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String inputLine = br.readLine();
			int numLines = Integer.parseInt(inputLine);
			
			for(int i=0; i < numLines; i++) {
				XYSeries line = new XYSeries(i);
				inputLine = br.readLine();
				st = new StringTokenizer(inputLine, " ");

				NumberFormat nf = NumberFormat.getInstance(Locale.ITALIAN);
				int linecode = nf.parse(st.nextToken()).intValue();
				int colorcode = nf.parse(st.nextToken()).intValue();
				int numDays = nf.parse(st.nextToken()).intValue();
				int increment = nf.parse(st.nextToken()).intValue();

				inputLine = br.readLine();
				st = new StringTokenizer(inputLine, " ");

				int point1X = nf.parse(st.nextToken()).intValue();
				float point1Y = nf.parse(st.nextToken()).floatValue();

				inputLine = br.readLine();
				st = new StringTokenizer(inputLine, " ");

				int point2X = nf.parse(st.nextToken()).intValue();
				float point2Y = nf.parse(st.nextToken()).floatValue();
				
				
				//The Calendar array starts at 0, the day number at 1, so a small adjustment was needed.
				Date day1 = dataset.getXDate(1, point1X-1);
				Date day2 = dataset.getXDate(1, point2X-1);
				
				line.add(day1.getTime(),point1Y);
				line.add(day2.getTime(), point2Y);
				sets.addSeries(line);
				
				
				
				Marker marker = new IntervalMarker(day1.getTime(),day2.getTime());
				marker.setAlpha(0.15f);
				marker.setLabelAnchor(RectangleAnchor.TOP_RIGHT);
				marker.setLabelTextAnchor(TextAnchor.TOP_LEFT);
				
				switch (colorcode){
				case 1:
					marker.setPaint(Color.BLUE);
					break;
				case 2:
					marker.setPaint(Color.YELLOW);
					break;
				case 13:
					marker.setPaint(Color.GREEN);
					break;
				case 18:
					marker.setPaint(Color.RED);
					break;
				}
				
				plot.addDomainMarker(marker);
			}
			in.close();
		} catch (IOException | ParseException e) {
			e.printStackTrace();
		}
		return sets;
	}
}
Here's the main: http://pastie.org/4655630

Code: Select all

import model.AbstractModel;
import model.CandleChartModel;
import model.ProcessData;
import view.CandleChartView;
import view.PNGView;
import controller.DefaultController;


public class Main {	
	public static void main(String[] args) {
		String market = args[0];
		String stockSymbol = args[1];
		String alarmType = args[2];
		String alarmFolder = args[3];
		String destinationFolder = args[4];
		
		String chartName = alarmType.substring(0, alarmType.lastIndexOf('_'))+"-"+alarmFolder.substring(alarmFolder.lastIndexOf("/")+1);
		
		ProcessData data = new ProcessData(market, alarmFolder, stockSymbol);

		//create Model and View
		AbstractModel myModel = new CandleChartModel(data);
		CandleChartView candleView = new CandleChartView(1280,600, myModel);
		PNGView pngView = new PNGView(1280,600, myModel);

		//tell Model about View. 
		myModel.addObserver(candleView);
		myModel.addObserver(pngView);	

		//create Controller. tell it about Model and View, initialize model
		DefaultController myController = new DefaultController();
		myController.addModel(myModel);
		myController.addView(candleView);
		myController.addView(pngView);

		//tell View about Controller 
		candleView.addController(myController);
		pngView.addController(myController);
		
		candleView.draw();
		pngView.save(destinationFolder+"/"+chartName);
		
		//program won't exit otherwise. it seams that some AWT is still opened...
		System.exit(0);
	}
}
the problem is that when the created custom timeline is added through DateAxis.setTimeline() method (CandleChartModel, line 83) for a lot of the charts, the contentPane does not appear, being a empty frame the only thing shown when trying to show the chart on a window and a empty PNG file when trying to save the chart into a file.


When the custom timeline is not used there's no problem whatsoever.


Any idea why this happens?


EDIT: I've put the code directly in the post.
Last edited by noriandir on Tue Sep 04, 2012 10:40 am, edited 2 times in total.

david.gilbert
JFreeChart Project Leader
Posts: 11734
Joined: Fri Mar 14, 2003 10:29 am
antibot: No, of course not.
Contact:

Re: Jframe not showing ContentPane

Post by david.gilbert » Mon Sep 03, 2012 8:37 pm

I get errors from most of the links that you posted, unfortunately. Maybe it is a temporary problem.

The timeline code is quite complex (and not bug-free), you should probably step through the code and check (for your data) whether it is throwing some exception somewhere that is preventing your chart from rendering correctly.
David Gilbert
JFreeChart Project Leader

:idea: Read my blog
:idea: Support JFree via the Github sponsorship program

noriandir
Posts: 8
Joined: Fri Jul 20, 2012 10:34 am
antibot: No, of course not.

Re: Jframe not showing ContentPane

Post by noriandir » Tue Sep 04, 2012 10:57 am

I've already done that, and for what I've seen, no exception is being thrown. But I'll do another check...

noriandir
Posts: 8
Joined: Fri Jul 20, 2012 10:34 am
antibot: No, of course not.

Re: Jframe not showing ContentPane

Post by noriandir » Thu Sep 06, 2012 9:47 am

Nope. That I've seen, there's no exception being thrown.
I have no idea of what could be causing this...

PS: forgot to say, but i'm using JFreeChart 1.0.14 and Java(TM) SE Runtime Environment (build 1.7.0-b147)

noriandir
Posts: 8
Joined: Fri Jul 20, 2012 10:34 am
antibot: No, of course not.

Re: Jframe not showing ContentPane

Post by noriandir » Mon Sep 10, 2012 12:28 pm

this is just weird...

debugging it, shows that the code breaks at JFrame.show() when exiting the if block. Eclipse shows that the Main thread isn't running any code, but the program gets stuck anyway, never exiting on his own. And obviously no chart is shown on the JFrame...

Locked