我做了一个涉及从串行线读取数据并将其表示在图形上的项目。到目前为止,我已经让serial reader class对grapher类中包含的数据集执行.validate()。 SerialReader类刚刚传递了整个grapher对象,并直接对其进行了更改。它还必须更新一组标签。该方法有效。
问题在于,逻辑正在更新存储在GUI对象中的模型。由于我为程序提供了许多新功能,因此需要读取更多串行线以获取不同类型的数据,甚至可以控制某些液压系统。因此,我需要更多的分离,模块化方法。
我现在有Main启动Grapher的实例,GUI类通过一个按钮启动时,会创建一个StrainTestObject并启动一个SerialReader线程。前者传递给后者,而StrainTestObject类保存我的系列和数据集以及其他元数据。创建完所有这些后,我将使用getter将数据集从StrainTestObject加载到GUI中。
当我这样做时,数据已正确添加到数据集中,但GUI上的图形未更新!我认为问题的根源在于Java是按值传递的,因此不会更新。有什么优雅的解决方案?有什么方法可以使串行读取器进程与模型以及与GUI分离?另外,还有一个额外的问题,用JFreeGraph重绘图形的最节省资源的方法是什么,它在Raspberry Pi上运行一段时间后开始变得很慢。
这是来自Grapher类的相关代码:
private void startSerialReader() {
if (s != null) {
if (s.comPort.isOpen()) { //Ensure port is ready
s.closePort();
}
}
s = new SerialReader(strainTestObject); //Make a new reader connection, give it access to data storage object
new Thread(s).start();
strainTestObject.removeAllSeries(); //reset the data if any, on start
dataset = strainTestObject.getDataset();
try {
dataset.validateObject();
} catch (InvalidObjectException e) {
e.printStackTrace();
}
chart.getXYPlot().setDataset(strainTestObject.getDataset());
labelCurrentValue.setText(String.valueOf(strainTestObject.getCurrentValue()));;
labelOffsetValue.setText(String.valueOf(strainTestObject.getOffsetValue()));
labelMaxValue.setText(String.valueOf(strainTestObject.getMaxValue()));
}
这是StrainTestObject类的相关代码:
void addDataToGraph(double val) throws InvalidObjectException {
invokeLater(() -> {
series.add(new Millisecond(), val);
});
}
来自构造函数
series = new TimeSeries("Strekk");
dataset = new TimeSeriesCollection();
dataset.addSeries(series);
现在,如果我更改代码以直接在grapher类中创建序列和数据集,并使SerialReader直接访问它,则效果很好。但是,如果将其保留在StrainTestObject类中,则不是这样。
如此SwingWorker
SwingWorker
中所示,您可以在实现example的过程中访问串行端口,而不必担心阻塞UI线程。当doInBackground()
通过轮询或响应回调获取新数据时,以中间结果调用SerialReader
。然后,您在publish()
的实现中将看到一个process()
,其中包含此过渡期间累积的所有结果。因为它在UI线程上运行,所以List
可以安全地更新图表的数据集process()
。监听的TimeSeriesCollection
将自动更新以响应。
我应该在
XYPlot
类中为PropertyChangeListener
创建方法Grapher
,并检查系列中的更改吗??
应该没有必要;更改StrainTestObject
将触发一个TimeSeriesCollection
,绘图将对此作出响应;更改任何组件DatasetChangeEvent
都会触发TimeSeries
,集合会响应。