简体   繁体   中英

JFreeChart is not updating ChartPanel, after reading data from serial port

I am trying to read some data from serial port and display the same using JFreeChart and ChartPanel. After I click button 'Aquire' I get new set of data from serial port. For the first time when panel is getting displayed, the values read from serial port is displayed. After I click the button 'Aquire', the values are getting populated in variable 'dataset' but they are not getting refreshed on the graph. Where am I going wrong? please help. Thanks in advance.

import java.awt.BasicStroke;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;

import javax.swing.GroupLayout;
import javax.swing.JApplet;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYLineAnnotation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.ChartChangeEvent;
import org.jfree.chart.event.ChartChangeListener;
import org.jfree.chart.panel.CrosshairOverlay;
import org.jfree.chart.plot.Crosshair;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleEdge;

public class DisplayPanel extends JApplet implements ActionListener
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    SimplePortComm spc;
    JFreeChart xylineChart;
    ChartPanel panel;
    XYSeriesCollection dataset;
    public static String sLLD;
    public static String sULD;

    Label lblTitle;
    Label lblMax, lblMin, lblULD, lblLLD;
    TextField txtMax, txtMin, txtULD, txtLLD;
    Label lblInrangeCount;
    TextField txtInrangeCount;
    Button bAquire, bSave, bLoad, bQuit;
    int i, nInRangeChannels;
    private Crosshair xCrosshair;
    private Crosshair yCrosshair;


    double dULD,dLLD;

    public DisplayPanel() {

        dataset = new XYSeriesCollection();

        spc = new SimplePortComm();


        lblTitle = new Label("Data Aquisition System for MCA");
        lblTitle.setPreferredSize(new Dimension(600, 20));

        lblMax = new Label("Max:");
        lblMin = new Label("Min:");
        lblULD = new Label("ULD:");
        lblLLD = new Label("LLD:");
        lblInrangeCount = new Label("Count in Range:");
        lblInrangeCount.setPreferredSize(new Dimension(60, 20));

        txtMax = new TextField(10);
        txtMax.setEditable(false);
        txtMin = new TextField(10);
        txtMin.setEditable(false);
        txtULD = new TextField(10);
        txtULD.setText("240.0");
        txtLLD = new TextField(10);
        txtLLD.setText("20.0");
        txtInrangeCount = new TextField(10);
        txtInrangeCount.setPreferredSize(new Dimension(60, 20));
        txtInrangeCount.setEditable(false);

        dULD = Double.parseDouble(txtULD.getText());
        dLLD = Double.parseDouble(txtLLD.getText());
        drawChart();

        bAquire = new Button("Aquire");      
        bAquire.setPreferredSize(new Dimension(20, 60));
        bAquire.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent aquire) {
                //panel.setRefreshBuffer(true); 
                System.setSecurityManager(null);// with out this statement, set_ports() throws null pointer exception
                spc.set_ports(dULD, dLLD);
                dataset = SimplePortComm.dataset;

                panel.repaint();
                panel.updateUI();

                System.out.print("Button: Aquire");
            }
          }
        );

        bSave = new Button("Save");
        bSave.setPreferredSize(null);
        bSave.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent save) {
                System.out.print("Button: Save");
            }
          }
        );

        bLoad = new Button("Load");
        bLoad.setPreferredSize(null);
        bLoad.addActionListener(
          new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent load) {
                System.out.print("Button: Load");
                sLLD = txtLLD.getText();
                sULD = txtULD.getText();

                txtInrangeCount.setText(Integer.toString(spc.getInRangeChannels()));                
            }
          }
        );

        bQuit = new Button("Quit");
        bQuit.setPreferredSize(new Dimension(10, 10));
        bQuit.addActionListener(new ActionListener() 
        {
            @Override
            public void actionPerformed(ActionEvent quit) {
                System.out.print("Button: Quit");
                System.exit(0);
            }
        });

        GroupLayout layout = new GroupLayout(getContentPane());     
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);

        layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(lblTitle)
            .addComponent(panel)
            .addGroup(layout.createSequentialGroup()
                .addComponent(bAquire)   
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(lblMax)
                    .addComponent(lblMin))
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(txtMax)
                    .addComponent(txtMin))
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(lblULD)
                    .addComponent(lblLLD))
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addComponent(txtULD)
                    .addComponent(txtLLD)))
         .addGroup(layout.createSequentialGroup()
            .addComponent(lblInrangeCount)
            .addComponent(txtInrangeCount))
         .addGroup(layout.createSequentialGroup()
            .addComponent(bSave)
            .addComponent(bLoad)
            .addComponent(bQuit))
      );

        layout.setVerticalGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(lblTitle)))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(panel)))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                .addGroup(layout.createSequentialGroup()
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(bAquire))
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(lblMax)
                        .addComponent(txtMax)
                        .addComponent(lblULD)
                        .addComponent(txtULD))                          
                    .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(lblMin)
                        .addComponent(txtMin)
                        .addComponent(lblLLD)
                        .addComponent(txtLLD))))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(lblInrangeCount)
                    .addComponent(txtInrangeCount))
            .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(bSave)
                    .addComponent(bLoad)
                    .addComponent(bQuit))
            );

        getContentPane().setLayout(layout);     
        getContentPane().setEnabled(true);
        getContentPane().setSize(1500, 1500);


    }
    public void drawChart()
    {
        System.setSecurityManager(null);// with out this statement, set_ports() throws null pointer exception
        spc.set_ports(dULD, dLLD);
        dataset = SimplePortComm.dataset;

        xylineChart = ChartFactory.createXYLineChart(
                 "Data Aquired" ,
                 "Time" ,
                 "Amplitude" ,
                 dataset ,
                 PlotOrientation.VERTICAL ,
                 true , true , false);

        panel = new ChartPanel(xylineChart, 650, 450, 180, 180, 800, 600, false, true, false, false, false, false);
        //panel.setRefreshBuffer(true);

        CrosshairOverlay crosshairOverlay = new CrosshairOverlay();
        this.xCrosshair = new Crosshair(Double.NaN, Color.BLACK, 
                new BasicStroke(0f));
        this.xCrosshair.setLabelVisible(true);
        this.yCrosshair = new Crosshair(Double.NaN, Color.BLACK, 
                new BasicStroke(0f));
        this.yCrosshair.setLabelVisible(true);
        crosshairOverlay.addDomainCrosshair(xCrosshair);
        crosshairOverlay.addRangeCrosshair(yCrosshair);
        panel.addOverlay(crosshairOverlay);

        panel.addChartMouseListener(new ChartMouseListener() {          
            @Override
            public void chartMouseMoved(ChartMouseEvent event) {
                Rectangle2D dataArea = panel.getScreenDataArea();
                JFreeChart chart = event.getChart();
                XYPlot plot = (XYPlot) chart.getPlot();
                ValueAxis xAxis = plot.getDomainAxis();
                double x = xAxis.java2DToValue(event.getTrigger().getX(), dataArea, 
                        RectangleEdge.BOTTOM);
                // make the crosshairs disappear if the mouse is out of range
                if (!xAxis.getRange().contains(x)) { 
                    x = Double.NaN;                  
                }
                double y = DatasetUtilities.findYValue(plot.getDataset(), 0, x);
                xCrosshair.setValue(x);
                yCrosshair.setValue(y);         
            }           
            @Override
            public void chartMouseClicked(ChartMouseEvent event) {
                Rectangle2D dataArea = panel.getScreenDataArea();
                System.out.println("Mouse clicked on the graph");
                XYPlot plot = (XYPlot) xylineChart.getPlot();

                ValueAxis xAxis = plot.getDomainAxis();
                double x = xAxis.java2DToValue(event.getTrigger().getX(), dataArea, 
                        RectangleEdge.BOTTOM);
                // make the crosshairs disappear if the mouse is out of range
                if (!xAxis.getRange().contains(x)) { 
                    x = Double.NaN;                  
                }
                double y = DatasetUtilities.findYValue(plot.getDataset(), 0, x);

                System.out.println("Graph click: " + x + ":" + y);

                xCrosshair.setValue(x);
                yCrosshair.setValue(y);

                XYItemRenderer renderer = plot.getRenderer();
                renderer.removeAnnotations();
                XYLineAnnotation mark = new XYLineAnnotation(x,0,x,250, new BasicStroke(), Color.BLACK);
                renderer.addAnnotation(mark);

                XYLineAnnotation low = new XYLineAnnotation(0.0f,dULD,400f,dULD, new BasicStroke(), Color.BLUE);
                renderer.addAnnotation(low);
                low.setToolTipText("low");
                XYLineAnnotation high = new XYLineAnnotation(0.0f,dLLD,400f,dLLD, new BasicStroke(), Color.MAGENTA);
                renderer.addAnnotation(high);
                high.setToolTipText("high");
                plot.setRenderer(renderer);
            }
        });

    }

    public void init() 
    {
        setBackground(Color.WHITE); 

        System.setSecurityManager(null);
        spc = new SimplePortComm();             
    }

    public static void main(String args[])
    {       
        DisplayPanel ds = new DisplayPanel();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub

    }

}

I don't know how SimplePortComm works, but your ActionListener is replacing the dataset that was used to create the chart. It works the first time because the original dataset is the one that xylineChart is listening to; the chart doesn't know about the new dataset . You can tell the chart about the change by using plot.setDataset(dataset);

Your ActionListener is also blocking the event dispatch thread , so you might want to use a SwingWorker like they show here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM