从 BufferedReader 接收数据时延迟图形显示

Delayed graph display when receiving data from BufferedReader

我对 JFreeChart 有一个非常严重的问题。我们在 Tinker Board 上用 C 编写了一个程序,它从 ADXL355 传感器获取数据并将其显示在 shell 中。 然后,使用我们在 Java 中编写的程序,我们使用缓冲 reader 接收数据并将其显示在图表中。当我们只在输出中打印接收到的数据时没有问题;但是当我们将数据发送到图形显示时,它显示有 30 秒的延迟,并且这个延迟会随着时间的推移而增加。

我们使用JFrame形式;这是 Java 边:

package client_time;

import com.bulenkov.darcula.DarculaLaf;
import com.mysql.jdbc.Connection;
import java.awt.Color;
import java.awt.FlowLayout;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import javax.swing.Timer;
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.Millisecond;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.omg.CORBA.TIMEOUT;


public class cha_time extends javax.swing.JFrame {
    
    public  TimeSeries TSx , TSy , TSz ;
    public  TimeSeriesCollection DataSetx , DataSety , DataSetz  ; 
    public  int x = 0 ;
    public  double Give_doubleX , Give_doubleY , Give_doubleZ ;
    public String Give_stringX , Give_stringY , Give_stringZ;
    public boolean Statuse = true ;
    public String line;
    public BufferedReader BR;
    public Process process;
    public InputStreamReader isr;
    public int i = 0 ;
    public  cha_time() {
        initComponents();
        line = "";
        Give_doubleX = 0.0;
        Give_doubleY = 0.0;
        Give_doubleZ = 0.0;
        
        
             TSx = new TimeSeries("", Millisecond.class);
              TSy = new TimeSeries("", Millisecond.class);
               TSz = new TimeSeries("", Millisecond.class);
             
             DataSetx =  new TimeSeriesCollection(TSx);
             DataSety =  new TimeSeriesCollection(TSy);
             DataSetz =  new TimeSeriesCollection(TSz);
            
             JFreeChart chartX = ChartFactory.createTimeSeriesChart("","", "",DataSetx ,true, true, false);
             JFreeChart chartY = ChartFactory.createTimeSeriesChart("","", "",DataSety ,true, true, false);
             JFreeChart chartZ = ChartFactory.createTimeSeriesChart("","", "",DataSetz ,true, true, false);
 //********************************************** X ***********************************************************************
                chartX.getPlot().setBackgroundPaint( Color.BLACK );
                XYPlot plotX =  chartX.getXYPlot();     
                ValueAxis axisX = plotX.getDomainAxis();
        axisX.setAutoRange(true);
        axisX.setFixedAutoRange(50000.0); 
        axisX = plotX.getRangeAxis();
        axisX.setAutoRange(true);
                XYPlot xyPlotX = (XYPlot) chartX.getPlot();// LINE color
                XYItemRenderer rendererX = xyPlotX.getRenderer();// LINE color
                rendererX.setSeriesPaint(0, Color.GREEN);// LINE color
 //*******************************************************************************************************************   
 //********************************************** Y ***********************************************************************  
                chartY.getPlot().setBackgroundPaint( Color.BLACK );
                XYPlot plotY =  chartY.getXYPlot();     
                ValueAxis axisY = plotY.getDomainAxis();
        axisY.setAutoRange(true);
        axisY.setFixedAutoRange(50000.0);
        axisY = plotY.getRangeAxis();
        axisY.setAutoRange(true);
                XYPlot xyPlotY = (XYPlot) chartY.getPlot();// LINE color
                XYItemRenderer rendererY = xyPlotY.getRenderer();// LINE color
                rendererY.setSeriesPaint(0, Color.magenta);// LINE color
 //*******************************************************************************************************************  
 //********************************************** Z *********************************************************************** 
                chartZ.getPlot().setBackgroundPaint( Color.BLACK );
                XYPlot plotZ =  chartZ.getXYPlot();     
                ValueAxis axisZ = plotZ.getDomainAxis();
        axisZ.setAutoRange(true);
        axisZ.setFixedAutoRange(50000.0); 
        axisZ = plotZ.getRangeAxis();
        axisZ.setAutoRange(true);
                XYPlot xyPlotZ = (XYPlot) chartZ.getPlot();// LINE color
                XYItemRenderer rendererZ = xyPlotZ.getRenderer();// LINE color
                rendererZ.setSeriesPaint(0, Color.ORANGE);// LINE color
 
           ChartPanel chpax = new ChartPanel(chartX,700, 150, 100, 100, 1000, 300, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled);//hatman bayad yek nemone az on sakhte beshe
           ChartPanel chpay = new ChartPanel(chartY,700, 150, 100, 100, 1000, 300, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled);//hatman bayad yek nemone az on sakhte beshe
           ChartPanel chpaz = new ChartPanel(chartZ,700, 150, 100, 100, 1000, 300, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled, rootPaneCheckingEnabled);//hatman bayad yek nemone az on sakhte beshe
           jPanel1.setLayout(new FlowLayout());
           jPanel2.setLayout(new FlowLayout());
           jPanel3.setLayout(new FlowLayout());
           jPanel1.add(chpax);
           jPanel2.add(chpay);
           jPanel3.add(chpaz);
           
       
    }

                         

    private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                               
      
        if(jToggleButton1.isSelected())
        {
            jToggleButton1.setText("DIS");
            
            ////////////////////////////////////////// Setup pipe //////////////////////////////////////////
try{
   //  process = Runtime.getRuntime().exec("/home/linaro/hopo/output" ); we try by this But it did not matter
       
 
                  ProcessBuilder processBuilder = new ProcessBuilder();
                  processBuilder.command("/home/linaro/hopo/output");
                  process =  processBuilder.start();
                  isr = new InputStreamReader(process.getInputStream());
                  BR = new BufferedReader(isr) ;
                 
}catch(Exception ex){System.out.println(ex);}  
            
                 Thread t = new Thread(new Runnable()
                 {
                   @Override
                  public void run()
                  {
    /////////////////////////////////////////////// WHILE ////////////////////////////////////////////////
            while(jToggleButton1.getText().equals("DIS")){
    ///////////////////////////////////////////// PIPE START /////////////////////////////////////////////
               
try {
             
              line = BR.readLine();
              System.out.println(line);
              
              Give_stringX = line.substring(0,12).toString().trim(); 
              Give_stringY = line.substring(14,26).toString().trim(); 
              Give_stringZ = line.substring(28,42).toString().trim(); 
            
                    Give_doubleX =   Double.parseDouble(Give_stringX);
                    Give_doubleY =   Double.parseDouble(Give_stringY);
                    Give_doubleZ =   Double.parseDouble(Give_stringZ);
                    
                    TSx.addOrUpdate(new Millisecond(), Give_doubleX);
                    TSy.addOrUpdate(new Millisecond(), Give_doubleY);
                    TSz.addOrUpdate(new Millisecond(), Give_doubleZ);
                   
                } catch (Exception ex) { //SQLException
                    System.out.println(ex);
                }
               
                }// END OF WHILE
            
        }
    });
    t.start();
            
        
        }else if(!jToggleButton1.isSelected())
        {
            try{
             process.destroy();
             process.destroyForcibly();
             isr.close();
             BR.close();
             jToggleButton1.setText("CO");
             System.out.println("goodbay");
             TSx.clear();
             TSy.clear();
             TSz.clear();
            }catch(Exception ex)
            {
                System.out.println(ex);
            }
            
        }
     
    }                                              

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Metal".equals(info.getName())) {
                     javax.swing.UIManager.setLookAndFeel(new DarculaLaf());
                    break;
                }
            }
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(cha_time.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new cha_time().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JToggleButton jToggleButton1;
    // End of variables declaration                   
  
}

您似乎在阻止 event dispatch thread. Instead, try the approach shown here using SwingWorker. As shown here and here, your implementation of doInBackground() can read asynchronously, publishing results as they arrive. In particular, as shown here, you can block doInBackground() while reading from your ProcessBuilder. As shown here,您的 process() 实现随后可以安全地更新图表的数据模型。

顺便说一句,考虑显示的方法 here 来驯服 GUI 编辑器。