# JFreeChart und das updaten



## Giftstachel (7. Jul 2008)

Hallo liebe Kundigen des fröhlichen Codens.

Ich hoffe, Ihr könnt mir helfen, ich selbst kann es leider nicht mehr, da ich mir schon seit fast 2 wochen den kopf über folgendes problem zerbreche.

ich würde gerne einen live-chart programmieren, der mir alle paar sekunden daten aus einer datenbank in den chart schreibt, und dieses grafisch ausgibt. 
db-anbindung, und alles andere klappt, jedoch wird bei mir im chart nur der erste datensatz angezeigt, und trotz neuer daten nicht verändert.

auf gut deutsch, das fireChartChanged(); klappt nicht.
ist es möglich, das ich irgendwo einen listener vergessen habe, oder der chart noch einen repaint braucht?
ich hab zwar schon alles mögliche ausprobiert, aber vielleicht hab ich was übersehen..

hier eine abgewandelte klasse des charts


```
package ausleser;

import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeListener;

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.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.RefineryUtilities;

public class testchart extends JFrame {

	public testchart(){
	    	super("mainTable");
	    	boolean isrunning = true;
	    	int firstRun = 0;
	    	
	    	while (isrunning == true)
	        {
	    		hilfsi++;
	    		System.out.println("mein main hilfsi = " + hilfsi);
	            try
	            {
	            	if (firstRun == 0)
	                {
	            		firstRun = 1;
	            		System.out.println("this.chartErzeugen();");
	            		this.chartErzeugen();
	            		this.initGUI();
	                   
	                }  
	            	SwingUtilities.invokeLater(new Runnable() {
	            		public void run() {
	            			System.out.println("Charts.this.chartUpdate(); ");
	            			testchart.this.updateChart(createDataset()); 
	            		}
	            	});
	                Thread.sleep(2000);
	                System.out.println("hab gut geschlafen");
	            }
	            catch (InterruptedException e)
	            {
	                e.getMessage();
	            }
	            catch (NullPointerException nullpe){}
	            catch (ArrayIndexOutOfBoundsException aioobex){}
	        }
	    }
	
	JFrame frame = new JFrame();
	JFreeChart chart;
	int hilfsi = 0;
	ChartPanel chartPanel = new ChartPanel(chart);
	
	
    public testchart(final String title) {
        final CategoryDataset dataset = createDataset();
        final JFreeChart chart = createChart(dataset);
        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500, 270));
    }

    private CategoryDataset createDataset() {

    	final String series1 = "Serie 1";

        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        int i = 0;
        double j = 0;
        double [] data = this.daten();
        String [] type = this.typus();
        while (i < 50){
        	dataset.addValue(data[i], series1, type[i]);
        	i++;
	       	j = j + 1.0;
        }

        return dataset;                
    }
    
    double []dataSet = new double[50];
    public double [] daten(){
    	int i = 0;
    	while(i < 50){
    		dataSet[i]= hilfsi + hilfsi/2;
                hilfsi++;
    		i++;
    		System.out.println("mein data hilfsi = " + hilfsi);
    	}
    	System.out.println(dataSet[0]);
    	return dataSet;
    }
    String []typen = new String[50];
    
    public String [] typus(){
    	int i = 0;
    	while(i < 50 ){
    		typen[i]=String.valueOf(hilfsi + hilfsi/3);
    		i++;
    		System.out.println("mein typus hilfsi = " + hilfsi);
    		System.out.println(typen[0]);
    	}
    	return typen;
    }
    
    public void chartErzeugen(){
    	chart = createChart(this.createDataset());
    }
    
    public void updateChart(CategoryDataset dataset){
    	this.createDataset().addChangeListener(this.chart.getCategoryPlot());
    	dataset.addChangeListener(this.chart.getCategoryPlot());
    	chart.fireChartChanged();
    	chartPanel.repaint();
    	frame.repaint();
    }   

    private JFreeChart createChart(final CategoryDataset dataset) {
    	final JFreeChart chart = ChartFactory.createLineChart(
            "Line Chart Demo 1",       // chart title
            "Type",                    // domain axis label
            "Value",                   // range axis label
            dataset,                   // data
            PlotOrientation.VERTICAL,  // orientation
            true,                      // include legend
            true,                      // tooltips
            false                      // urls
        );

        chart.setBackgroundPaint(Color.white);

        final CategoryPlot plot = (CategoryPlot) chart.getPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setRangeGridlinePaint(Color.white);

        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        rangeAxis.setAutoRangeIncludesZero(true);

        return chart;
    }
    
    public void initGUI(){
    	
        chart.setBackgroundPaint(new Color(220,220,220));
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setBackground(Color.lightGray);
        chartPanel.setPreferredSize(new java.awt.Dimension(750, 410));
        frame.setContentPane(chartPanel);
        frame.pack();
        RefineryUtilities.centerFrameOnScreen(frame);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(final String[] args) {
    	testchart testchart = new testchart();
    }

}
```

(ja, ich weiß, klassennamen werden groß geschrieben )
habs nur auf die schnelle umgebaut, damit man es leichter testen kann.

für jede hilfe wäre ich echt dankbar.
lg
giftie


----------



## Gast (7. Jul 2008)

also irgendwie versteh ich diese methode nicht

  public void updateChart(CategoryDataset dataset){
       this.createDataset().addChangeListener(this.chart.getCategoryPlot());
       dataset.addChangeListener(this.chart.getCategoryPlot());
       chart.fireChartChanged();
       chartPanel.repaint();
       frame.repaint();
    }    

du übergibst der was, benutzt das aber gar nicht.
in der ersten zeile addest du da nen changelistener auf ein objekt, was danach sowieso verschwindet, oder benutzt du das, was dir da mit this.createDataSet() machst irgendwo?


----------



## SlaterB (7. Jul 2008)

updateChart wird auch mit einem createDataSet() aufgerufen,
das sind dann schon zwei, die zwar auch einen Listener bekommen,
aber sonst nix weiter mit dem Programm zu tun haben,

die angezeigte Chart oder deren DataSet bleibt unberührt

---------

Klassen groß schreiben!!

-------

der Konstruktor

 public testchart(final String title) { 
        final CategoryDataset dataset = createDataset(); 
        final JFreeChart chart = createChart(dataset); 
        final ChartPanel chartPanel = new ChartPanel(chart); 
        chartPanel.setPreferredSize(new Dimension(500, 270)); 
    } 


ist ohne Verwendung, doppelter Code?


----------



## Giftstachel (7. Jul 2008)

ja, richtig. ist doppelt, und kann in diesem fall weg, im original wirds gebraucht. habe ich übersehen, beim zusammenstöpseln des codes.

klassennamen groß, ich weiß ebenfalls ein "bastelfehler"

der chart bleibt unberührt?
ich dachte, das .fireChartChanged();  benutzt den listener automatisch, der auf dem dataset liegt? oder hab ich das falsch verstanden? *grübel*


----------



## SlaterB (7. Jul 2008)

was soll denn bei fireChartChanged() passieren?
die Chart guckt in hier DataSet, welches sich nicht geändert hat,

falls irgendwie ein älterer Zustand bekannt ist, passiert nix,
bestenfalls wird die Chart mit den gleichen Daten neugezeichnet,

> benutzt den listener automatisch

warum sollte irgendwer irgendwo definierte Listener verwenden?
die Chart weiß doch gar nix von deinen anderen DataSets, unabhängig davon, ob der Listener was mit der Sache zu tun hat


wenn man übrigens B bei A als Listener einfügst, dann kennt vielleicht A nun B,
aber B noch längst nicht A


---------

damit irgendwas mal ins Rollen kommt, brauchst du schon entweder
a) chart.verwendeNeuesDataSet(was neues)
oder 
b) chart.aktuellesDataSet.aendereDich()

aber irgendwo separate DataSets anzulegen hat offensichtlich auf andere Charts keine Auswirkungen,
fire() hin oder her

edit:
oder richtig, wie du es machst 
c) eine neue Chart erstellen,
aber die dann auch richtig anzeigen


----------



## Giftstachel (7. Jul 2008)

jep. das klingt irgendwie logisch^^

allerdings bei dem versuch, den chart mit dem neuen dataset zu füllen, klappt das auch nicht 


```
public void updateChart(){
       this.chart = createChart(createDataset());
       chart.setTitle("argh");
       chart.fireChartChanged();
       chartPanel.repaint();
       frame.repaint();
    }
```

das dataset ändert sich jedoch, wie man in der kosole sehen kann.


----------



## SlaterB (7. Jul 2008)

ChartPanel zeigt die Chart an, die ihm im Konstruktor übergeben wurde,

was nützt es, wenn du irgendwo in eine deiner Klassenvariablen ein neue Chart ablegst,
das ist dem ChartPanel egal


immer das gleiche Spiel, nur eine Stufe weiter


----------



## Giftstachel (7. Jul 2008)

oh. man... so simpel..

vielen vielen dank. *froi*

hat eigentlich nur noch this.chartPanel.updateUI(); gefehlt...

da muss man auch erstmal drauf kommen^^

so muss das dann aussehen:

```
public void updateChart(){
    	this.chart = createChart(createDataset());
        this.chart.setBackgroundPaint(new Color(220,220,220));
        this.chartPanel.setBackground(Color.lightGray);
        this.chart.fireChartChanged();
        this.chartPanel.setChart(this.chart);
        this.chartPanel.updateUI();
        this.frame.setContentPane(this.chartPanel);
    }
```



also alles in allem, wenn mal jemand das gleiche prob hat, wie ich:
(kann man sicher noch optimieren, aber fürs erste klappts)


```
package ausleser;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

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.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.RefineryUtilities;

public class testchart extends JFrame {

   public testchart(){
          super("mainTable");
          boolean isrunning = true;
          int firstRun = 0;
          
          while (isrunning == true)
           {
             hilfsi++;
              try
               {
                  if (firstRun == 0)
                   {
                     firstRun = 1;
                     this.chartErzeugen();
                     this.initGUI();
                      
                   } 
                  SwingUtilities.invokeLater(new Runnable() {
                     public void run() {
                        testchart.this.updateChart();
                     }
                  });
                   Thread.sleep(2000);
               }
               catch (InterruptedException e)
               {
                   e.getMessage();
               }
               catch (NullPointerException nullpe){}
               catch (ArrayIndexOutOfBoundsException aioobex){}
           }
       }
   
   JFrame frame = new JFrame();
   JFreeChart chart;
   int hilfsi = 0;
   ChartPanel chartPanel = new ChartPanel(chart);
   double []dataSet = new double[50];
   String []typen = new String[50];
   
   
   public double [] daten(){
       int k = 0;
       while(k < 50){
          dataSet[k]= hilfsi + hilfsi/2;
          hilfsi++;
          k++;
       }
       return dataSet;
    }
     
   public String [] typus(){
       int j = 0;
       while(j < 50 ){
          typen[j]=String.valueOf(j);
          j++;
       }
       return typen;
    }

    private CategoryDataset createDataset() {

       final String series1 = "Serie 1";

        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        int i = 0;
        double [] data = this.daten();
        String [] type = this.typus();
        while (i < 50){
           dataset.addValue(data[i], series1, type[i]);
           i++;
        }
        System.out.println("dataset geändert" + data[0] + " typus = " + type[0]);
        return dataset;               
    }
 
    public void chartErzeugen(){
       chart = createChart(createDataset());
    }
   
    public void updateChart(){
    	this.chart = createChart(createDataset());
        this.chart.setBackgroundPaint(new Color(220,220,220));
        this.chartPanel.setBackground(Color.lightGray);
        this.chart.fireChartChanged();
        this.chartPanel.setChart(this.chart);
        this.chartPanel.updateUI();
        this.frame.setContentPane(this.chartPanel);
    }   

    private JFreeChart createChart(final CategoryDataset dataset) {
       final JFreeChart chart = ChartFactory.createLineChart(
            "Line Chart Demo 1",       // chart title
            "Type",                    // domain axis label
            "Value",                   // range axis label
            dataset,                   // data
            PlotOrientation.VERTICAL,  // orientation
            true,                      // include legend
            true,                      // tooltips
            false                      // urls
        );

        chart.setBackgroundPaint(Color.white);

        final CategoryPlot plot = (CategoryPlot) chart.getPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setRangeGridlinePaint(Color.white);

        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        rangeAxis.setAutoRangeIncludesZero(true);

        return chart;
    }
   
    public void initGUI(){
       
        chart.setBackgroundPaint(new Color(220,220,220));
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setBackground(Color.lightGray);
        chartPanel.setPreferredSize(new java.awt.Dimension(750, 410));
        frame.setContentPane(chartPanel);
        frame.pack();
        RefineryUtilities.centerFrameOnScreen(frame);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    public static void main(final String[] args) {
       testchart testchart = new testchart();
    }

}
```


nicht vergessen, klassennamen IMMER groß schreiben


----------

