java - JFreeChart 时间序列不刷新

标签 java swing jfreechart

我使用 this thread 中的代码开发了一个时间序列 JFreeChart 。 我想将其添加到我的主面板中,其中包含其他四个面板。所以我创建了一个方法

 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);
    }

}

我在我的面板构造函数之一中调用此代码,如下所示:

   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);
    }

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

最佳答案

好吧,我想我已经发现了你的问题,但如果不看看你如何使用所有这些代码,我就无法完全确定。

您的主要问题在于:

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 的新实例并启动它。这没有任何意义:

  1. 您的封闭 PrepareChart 实例从未启动(因此您看不到它动态更新)
  2. 任何人/任何事物都无法访问您在可运行对象中创建的实例,因此该实例会在 AWT 事件队列中永远丢失。

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

public JPanel getChartPanel() {

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

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

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上执行所有这些操作。

顺便说一句,在 getter 方法中调用 start() 是很奇怪的。

关于java - JFreeChart 时间序列不刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11188219/

相关文章:

java - 是否有任何工具可以检测类成员变量中可能出现的 NullPointerException

java - 缩放 Graphics2D 对象会移动它

java - 在 actionListener 中将 JPanel 添加到 contentPane

java - WindowsLookAndFeel 上的 JProgressBar 仅以 5% 的增量更新

java - 在同一 Jfreechart Piedataset 上使用不同的数据集

java - 我可以根据比例缩放ValueAxis吗?

java - 在 java 中逐步询问 levenberg-marquardt

java - 在 Spring boot 应用程序项目中使用 Wildfly

java - 使用正则表达式替换不同的子字符串

Java JFreeChart - 获取边界点坐标