现在我有一个可以读取串行数据的Java文件,它只是在控制台中打印出来。在另一个文件中,我有一个JFreeChart图表,可以将随机数据生成到实时图表中。
这些文件都在同一个项目中。如何将串行数据添加到实时图表中,而不是我现在使用的随机数据?
下面的第一个代码是实时图表的文件。
public class test224 extends ApplicationFrame implements ActionListener {
String s;
String tempbuff;
private TimeSeries series;
private double lastValue = 10.0;
private Timer timer = new Timer(1000, this);
DynamicTimeSeriesCollection dataset;
float[] newData = new float[1];
public test224(final String title) {
super(title);
this.series = new TimeSeries("Sensor Value", Millisecond.class);
final TimeSeriesCollection dataset = new TimeSeriesCollection(this.series);
final JFreeChart chart = createChart(dataset);
timer.setInitialDelay(1000);
chart.setBackgroundPaint(Color.LIGHT_GRAY);
final JPanel content = new JPanel(new BorderLayout());
final ChartPanel chartPanel = new ChartPanel(chart);
content.add(chartPanel);
chartPanel.setPreferredSize(new java.awt.Dimension(800, 500));
setContentPane(content);
timer.start();
}
private JFreeChart createChart(final XYDataset dataset) {
final JFreeChart result = ChartFactory.createTimeSeriesChart(
"Dynamic Line Chart of Arduino Data",
"Zeit",
"Wert",
dataset,
true,
true,
false
);
final XYPlot plot = result.getXYPlot();
plot.setBackgroundPaint(new Color(0xffffe0));
plot.setDomainGridlinesVisible(true);
plot.setDomainGridlinePaint(Color.lightGray);
plot.setRangeGridlinesVisible(true);
plot.setRangeGridlinePaint(Color.lightGray);
ValueAxis xaxis = plot.getDomainAxis();
xaxis.setAutoRange(true);
xaxis.setFixedAutoRange(60000.0);
xaxis.setVerticalTickLabels(true);
ValueAxis yaxis = plot.getRangeAxis();
yaxis.setRange(0.0, 300.0);
return result;
}
public void actionPerformed(final ActionEvent e) {
final double factor = 0.9 + 0.2*Math.random();
this.lastValue = this.lastValue * factor;
final Millisecond now = new Millisecond();
this.series.add(new Millisecond(), this.lastValue);
}
public static void main(final String[] args) {
final test224 demo = new test224("Dynamic Line And TimeSeries Chart");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
在执行的操作中是生成随机数据的位置。然后在另一个文件的代码中,这会将Arduino串行数据打印到控制台,那么我怎样才能将它显示在实时图形中呢?
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
inputLine=input.readLine();
System.out.println(inputLine);
}
catch (Exception e) {
}
}
}
答案 0 :(得分:1)
您需要通过合并类别将serialEvent
的内容移动到actionPerformed
方法中,或者在public addDataPoint(double point)
中提供可以从中调用的test224
方法包含序列事件的类。我认为在任何一种情况下,您都需要将serialEvent中的处理移动到一个单独的线程中。
您可以尝试这样的事情:
@Override
public void actionPerformed(final ActionEvent e) {
//Initialise the serial port here before starting the new thread
Runnable task = new Runnable() {
@Override
public void run() {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
inputLine = input.readLine();
System.out.println( inputLine );
final Millisecond now = new Millisecond();
series.add(new Millisecond(), Double.parseDouble(inputLine));
} catch (Exception e) {
}
}
}
};
Thread serialThread = new Thread(task);
serialThread.start();
}
public addDataPoint(double point)
解决方案更可取,因为您保持关注点分离。
public synchronized void serialEvent(SerialPortEvent oEvent) {
if (oEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
inputLine=input.readLine();
System.out.println(inputLine);
dataChart.addPoint(Double.parseDouble(inputLin));
} catch (Exception e) {
}
}
}
您仍需要确保在单独的线程上监视串行点。
答案 1 :(得分:1)
我不愿意更新图表的数据集,而不会将调用包含在适合Runnable
的{{1}}中。此example会从匿名后台主题更新invokeLater()
。
更好的是,使用TableModel
,如图所示here。您可以使用SwingWorker
方法和doInBackground()
有用的结果来操纵串口,相信publish()
会在event dispatch thread上运行。