JFreeChart的实时曲线图的例子

好久没更新过技术相关的东西了,今天要开始写管理控制台,里面需要用到实时曲线图,决定使用JFreeChart做,这东西还真的挺好用,简单的几句代码就能搭建一个看起来不错的程序:-)
预览图:

/*
 * RealTimeGraphPanel.java
 *
 * Created on 2008年10月1日, 下午2:04
 */
package cn.bearice.ipcontroller.manager.graph;

import cn.bearice.java.util.StopableThread;
import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;

/**
 *
 * @author  Bearice
 */
public class RealTimeGraphPanel extends javax.swing.JPanel {

    private static final long serialVersionUID = 8250077948583513551L;
    TimeSeriesCollection tcl;
    ChartPanel cp;
    JFreeChart jfc;
    ArrayList tss = new ArrayList();
    TimeSeries tts = new TimeSeries("Avg.", Second.class);

    /** Creates new form RealTimeGraphPanel */
    public RealTimeGraphPanel() {
        tcl = new TimeSeriesCollection();
        tcl.addSeries(tts);
        addTimeSeries();
        jfc = ChartFactory.createTimeSeriesChart("Random Numbers", "Time", "Value", tcl, true, true, false);
        XYPlot xyplot = jfc.getXYPlot();
        ValueAxis valueaxis = xyplot.getDomainAxis();
        valueaxis.setAutoRange(true);
//        valueaxis.setInverted(true);
        valueaxis = xyplot.getRangeAxis();
        valueaxis.setAutoRange(true);
        cp = new ChartPanel(jfc);
        initComponents();
    }

    public void addTimeSeries() {
        TimeSeries timeSeries = new TimeSeries("Random" + tss.size(), Second.class);
        tcl.addSeries(timeSeries);
        tss.add(timeSeries);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Test Chart");
        final RealTimeGraphPanel rtgp = new RealTimeGraphPanel();
        frame.getContentPane().add(rtgp, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);

        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent windowevent) {
                System.exit(0);
            }
        });
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // 
    private void initComponents() {

        jbtnStartStop = new javax.swing.JButton();
        jPanel1 = (cp);
        jbtnFixed = new javax.swing.JButton();
        jbtnScaled = new javax.swing.JButton();
        jbtnClear = new javax.swing.JButton();
        jbtnAdd = new javax.swing.JButton();

        setName("Form"); // NOI18N

        jbtnStartStop.setText("Start");
        jbtnStartStop.setName("jbtnStartStop"); // NOI18N
        jbtnStartStop.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnStartStopActionPerformed(evt);
            }
        });

        jPanel1.setName("jPanel1"); // NOI18N

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 261, Short.MAX_VALUE)
        );

        jbtnFixed.setText("Fixed");
        jbtnFixed.setName("jbtnFixed"); // NOI18N
        jbtnFixed.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnFixedActionPerformed(evt);
            }
        });

        jbtnScaled.setText("Scaled");
        jbtnScaled.setName("jbtnScaled"); // NOI18N
        jbtnScaled.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnScaledActionPerformed(evt);
            }
        });

        jbtnClear.setText("Clear");
        jbtnClear.setName("jbtnClear"); // NOI18N
        jbtnClear.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnClearActionPerformed(evt);
            }
        });

        jbtnAdd.setText("Add");
        jbtnAdd.setName("jbtnAdd"); // NOI18N
        jbtnAdd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbtnAddActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jbtnStartStop)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jbtnFixed)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jbtnScaled)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jbtnClear)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jbtnAdd)
                .addContainerGap(53, Short.MAX_VALUE))
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jbtnStartStop)
                    .addComponent(jbtnFixed)
                    .addComponent(jbtnScaled)
                    .addComponent(jbtnClear)
                    .addComponent(jbtnAdd))
                .addContainerGap())
        );
    }// 

    class T1 extends StopableThread {

        @Override
        protected void loop() throws InterruptedException {
            for (TimeSeries timeSeries : tss) {
                double d = randomNum();
                num = (num + d) / 2;
                timeSeries.add(new Second(), d);
            }
            tts.add(new Second(), num);
            Thread.sleep(1000);
        }
        double num;
        Random rand = new Random();

        private double randomNum() {
            return rand.nextGaussian();
        }
    }
    T1 t1;
private void jbtnStartStopActionPerformed(java.awt.event.ActionEvent evt) {
    if (t1 == null) {
        t1 = new T1();
        t1.start();
        jbtnStartStop.setText("stop");
    } else {
        t1.exit();
        t1 = null;
        jbtnStartStop.setText("start");
    }
}

private void jbtnFixedActionPerformed(java.awt.event.ActionEvent evt) {
//    cp.setAutoscrolls(true);
    XYPlot xyplot = jfc.getXYPlot();
    ValueAxis valueaxis = xyplot.getDomainAxis();
    valueaxis.setFixedAutoRange(50000);
}

private void jbtnScaledActionPerformed(java.awt.event.ActionEvent evt) {
    XYPlot xyplot = jfc.getXYPlot();
    ValueAxis valueaxis = xyplot.getDomainAxis();
    valueaxis.setFixedAutoRange(0);
}

private void jbtnClearActionPerformed(java.awt.event.ActionEvent evt) {
    for (TimeSeries timeSeries : tss) {
        timeSeries.clear();
    }
}

private void jbtnAddActionPerformed(java.awt.event.ActionEvent evt) {
    addTimeSeries();
}
    // Variables declaration - do not modify
    private javax.swing.JPanel jPanel1;
    private javax.swing.JButton jbtnAdd;
    private javax.swing.JButton jbtnClear;
    private javax.swing.JButton jbtnFixed;
    private javax.swing.JButton jbtnScaled;
    private javax.swing.JButton jbtnStartStop;
    // End of variables declaration
}

PS:里面用到了一个自己实现的StopableThread,代码如下:

/*
 * Copyrights (C) 2008 Bearice ([email protected])
 * Release under GNU/GPL Version 2.
 */
package cn.bearice.java.util;

/**
 * 可以停止的线程。
 * @author Bearice
 */
public abstract class StopableThread extends Thread {

    protected boolean exit = false;

    /**
     * 线程开始后,进入循环前调用。
     */
    protected void before() {
        //System.out.println("Starting thread: "+this);
    }

    /**
     * 线程退出前,循环退出后调用。
     */
    protected void after() {
       // System.out.println("Ending thread: "+this);
    }

    /**
     * 循环体代码。
     * @throws java.lang.InterruptedException
     */
    protected abstract void loop() throws InterruptedException;

    /**
     * 指示线程退出循环。
     */
    public synchronized void exit() {
        exit = true;
        interrupt();
    }

    @Override
    public final void run() {
        before();
        while (!exit) {
            try {
                loop();
            } catch (InterruptedException ex) {
            }
        }
        after();
    }
}
>_<|| 我手贱!!这个有问题!绝对有问题!!一般般啦,真的很一般般。还不错哦~小表扬一下!GJ!乃就是新世界的神様了,快去拯救世界吧! (1 votes, average: 1.00 out of 5)
Loading...

2 人次吐槽

  1. Kingsam Chen说道:
    骑着 Unknown Unknown 和 Unknown Unknown

    JFC……感觉比MFC只管多了,直逼WinForm……
    ps:考拉把这个评论放在页面内,顺便把验证码去掉~

  2. movielike说道:
    骑着 Internet Explorer 6.0 Internet Explorer 6.0 和 Windows XP Windows XP
    Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; sbcydsl 3.12; YComp 5.0.0.0; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; .NET CLR 2.0.50727; Zune 2.0)

    Sign: kxdrb Hello!!! zsmbs and 2985wbvdddzsws and 671 My Comments: Nice blog!

春菜 对话 相声
双击调戏
双击调戏