【发布时间】:2020-02-10 09:17:48
【问题描述】:
我做了一个项目,涉及从串行线路读取数据并将其表示在图表上。到目前为止,我已经让我的 serial reader 类 对我的 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 类中,则不会。
【问题讨论】:
-
Java 通过引用传递对象。然而,有些对象,比如 String 对象是不可变的。
-
Java 是传值,但值是对数据的引用。您用于更新图表的代码是什么。
-
@NomadMaker 对,我现在看到只有原始类型是按值传递的。嗯 - 这将使我的方法可行,不是吗?
-
真的是所有东西的传值,但是对象的值是一个引用。
-
使用this approach,您可以在
doInBackground()的实现中访问串口,而不必担心阻塞UI线程。
标签: java model-view-controller jfreechart