问题
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
}
回答1:
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.
来源:https://stackoverflow.com/questions/64842393/delayed-graph-display-when-receiving-data-from-bufferedreader