I have a very serious problem with JFreeChart . We wrote a program by C on the Tinker Board that takes the data from the ADXL355 sensor and displays it in shell. Then, with a program we wrote in Java, we received the data using a buffered reader and displayed it in graphs. There is no problem when we print the received data only in the output; but when we send the data to the graph for display, it is displayed with a delay of 30 seconds and this delay increases over time.
We use JFrame
form; here is Java side:
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
}
It looks like you're blocking the 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, your implementation of process()
can then safely update the chart's data model.
As an aside, consider the approach shown here to tame the GUI editor.