JFreeChart时间序列不刷新 [英] JFreeChart timeseries is not refreshing

查看:31
本文介绍了JFreeChart时间序列不刷新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过使用此线程.我想将其添加到我的主面板中,该主面板包含其他四个面板.所以我创建了一个方法

I have developed a timeseries JFreeChart by using code from this thread. I want to add this to my main panel, which contains four other panels. So I created a method

 package com.garnet.panel;

    import java.awt.*;
    import java.awt.event.*;
    import java.text.*;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import javax.swing.JPanel;
    import javax.swing.Timer;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.axis.*;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.chart.renderer.xy.XYItemRenderer;
    import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
    import org.jfree.data.time.DynamicTimeSeriesCollection;
    import org.jfree.data.time.Second;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.ui.RectangleInsets;
    import org.jfree.ui.RefineryUtilities;


    public class PrepareChart {

    private static final String TITLE = "Dynamic Series";
    private static final int COUNT = 2 * 60;
    private Timer timer;
    private static float lastValue = 49.62f;
    ValueAxis axis;
    DateAxis dateAxis;
    public JFreeChart chart;
    public PrepareChart() {
        super();

        final DynamicTimeSeriesCollection dataset = new DynamicTimeSeriesCollection(1, COUNT, new Second());

      // Get the calender date time which will inserted into time series chart
      // Based on time we are getting here we disply the chart
      Calendar calendar = new GregorianCalendar();
      int date = calendar.get(Calendar.DAY_OF_MONTH);
      int month = calendar.get(Calendar.MONTH);
      int year = calendar.get(Calendar.YEAR);
      int hours = calendar.get(Calendar.HOUR_OF_DAY);
      int minutes = calendar.get(Calendar.MINUTE);
      int seconds = calendar.get(Calendar.SECOND);
       System.out.println("In caht constructor methoed");
      dataset.setTimeBase(new Second(seconds, minutes-2, hours, date, month, year));
      dataset.addSeries(gaussianData(), 0, "Currency Rate");

       chart= createChart(dataset);

        timer = new Timer(969, new ActionListener() {

            float[] newData = new float[1];

            @Override
            public void actionPerformed(ActionEvent e) {
                newData[0] = randomValue();
                System.out.println("In caht timer methoed");
                dataset.advanceTime();
                dataset.appendData(newData);
            }
        });


    }

    private float randomValue() {

      double factor = 2 * Math.random();
      if (lastValue >51){
        lastValue=lastValue-(float)factor;
      }else {
        lastValue = lastValue + (float) factor;
      }
        return  lastValue;
    }
    // For getting the a random float value which is supplied to dataset of time series chart
    private float[] gaussianData() {
        float[] a = new float[COUNT];
        for (int i = 0; i < a.length; i++) {
            a[i] = randomValue();
        }
        return a;
    }

    // This methode will create the chart in the required format
    private JFreeChart createChart(final XYDataset dataset) {  

        final JFreeChart result = ChartFactory.createTimeSeriesChart(TITLE, "hh:mm:ss", "Currency", dataset, true, true, false);

        final XYPlot plot = result.getXYPlot(); 

        plot.setBackgroundPaint(Color.BLACK);
        plot.setDomainGridlinePaint(Color.WHITE);
        plot.setRangeGridlinePaint(Color.WHITE);
        plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
        plot.setDomainCrosshairVisible(true);
        plot.setRangeCrosshairVisible(true);

        XYItemRenderer r = plot.getRenderer();

        if (r instanceof XYLineAndShapeRenderer) {

            XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
                renderer.setBaseShapesVisible(true);

                renderer.setBaseShapesFilled(true);
                renderer.setBasePaint(Color.white);
                renderer.setSeriesPaint(0,Color.magenta);
        }

      dateAxis= (DateAxis)plot.getDomainAxis();

      DateTickUnit unit = null;
      unit = new DateTickUnit(DateTickUnitType.SECOND,30);

      DateFormat chartFormatter = new SimpleDateFormat("HH:mm:ss");
      dateAxis.setDateFormatOverride(chartFormatter);
      dateAxis.setTickUnit(unit);       

      NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
      rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
      rangeAxis.setRange(lastValue-4, lastValue+4);

        return result;
    }

    public void start(){
        timer.start();
    }


    public JPanel getChartPanel(){

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                PrepareChart chart = new PrepareChart(); 
                System.out.println("In caht getter methoed");
                chart.start();
            }
        });
        return new ChartPanel(chart);
    }

}

我正在这样的一个面板构造函数中调用此代码:

I am calling this code inside one of my panel constructors like this:

   public class ChartPanel extends JPanel{

    private Dimension dim;
    private PrepareChart chart;
    public JPanel jChart;

    public ChartPanel(){
        dim = super.getToolkit().getScreenSize();
        this.setBounds(2,2,dim.width/4,dim.height/4);
        chart = new PrepareChart();
        jChart =chart.getChartPanel();       

        this.add(jChart);
    }

但是当我将此面板添加到框架中时,图形不会动态更改.

But when I add this panel to the frame, the graph is not changing dynamically.

推荐答案

好的,我想我已经发现了您的问题,但是我无法完全确定是否不了解您如何使用所有这些代码.

OK, I think I have spotted your problem, but I can't be completely sure without seeing how you use all this code.

您的主要问题在这里:

public JPanel getChartPanel(){

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                PrepareChart chart = new PrepareChart(); 
                System.out.println("In caht getter methoed");
                chart.start();
            }
        });
        return new ChartPanel(chart);
    }

在您的Runnable中,您重新创建PrepareChart的新实例并启动它.这没有任何意义:

In your Runnable, you recreate a new instance of PrepareChart and you start it. This does not make any sense:

  1. 您随附的 PrepareChart 实例永远不会启动(因此您不会看到它动态更新)
  2. 任何人都无法访问您在可运行对象中创建的实例,因此该实例如果在AWT事件队列中永远丢失.
  1. Your enclosing PrepareChart instance is never started (hence you don't see it updated dynamically)
  2. The instance you create in your runnable cannot be reached by anyone/anything so that instance if lost forever in the AWT event-queue.

因此,我只会使用以下内容:

So instead, I would only be using the following:

public JPanel getChartPanel() {

    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            start();
        }
    });
    return new ChartPanel(chart);
}

这是我写的一个小的主要方法,似乎可以解决问题.

This is a small main method that I wrote which seemed to do the trick.

public static void main(String[] args) {
    PrepareChart prepareChart = new PrepareChart();
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(prepareChart.getChartPanel());
    frame.pack();
    frame.setVisible(true);
}

考虑重命名您的类 ChartPanel ,因为它与令人困惑的JFreeChart名称冲突.另外,我看不到它的用法,因为您可以直接在PrepareChart返回的ChartPanel上执行所有操作.

Consider renaming your class ChartPanel because it is conflicting with the names of JFreeChart which is confusing. Also, I don't see the use of it since you could perform all that directly on the ChartPanel returned by PrepareChart.

顺便说一句,用getter方法将对 start()的调用放在一个奇怪的地方.

Btw, it is quite odd to put the call to start() in a getter-method.

这篇关于JFreeChart时间序列不刷新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆