java - 添加新数据后更新 JFreeChart 绘图,MVC 方法?

标签 java model-view-controller jfreechart

我做了一个项目,涉及从串行线路读取数据并将其表示在图表上。到目前为止,我已经让我的串行读取器类对我的grapher类中包含的数据集执行了.validate()。 SerialReader 类刚刚传递了整个 grapher 对象并直接对其进行了更改。它还必须更新一组标签。这个方法奏效了。

问题在于逻辑正在更新存储在 GUI 对象中的模型。由于我正在为程序添加许多新功能,读取更多不同类型数据的串行线,甚至控制一些液压系统。所以我需要更多独立的、模块化的方法。

我现在有 Main 启动 GUI 类 Grapher 的实例,当使用按钮启动时,它会创建一个 StrainTestObject 并启动SerialReader 线程。前者传递给后者,StrainTestObject 类保存我的系列和数据集以及其他元数据。当这些都创建完成后,我使用 getter 将数据集从 StrainTestObject 加载到 GUI 中。

Class diagram

当我这样做时,数据已正确添加到数据集中,但 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所示example ,您可以在 doInBackground() 的实现中访问串行端口,而不必担心阻塞 UI 线程。当您的 SerialReader 通过轮询或响应回调获取新数据时,使用中间结果调用 publish()。然后,您的 process() 实现将看到一个 List,其中包含在此期间积累的所有结果。由于它在 UI 线程上运行,process() 可以安全地更新图表的数据集,即 TimeSeriesCollection。监听的 XYPlot 将更新自身作为响应。

Should I make a method PropertyChangeListener in Grapher for the StrainTestObject class, and check for changes in the series…?

应该没有必要;改变 TimeSeriesCollection 将触发 DatasetChangeEvent,绘图将响应该事件;改变任何组件 TimeSeries 都会触发 SeriesChangeEvent,封闭的集合将响应该事件。无论哪种情况,封闭的 ChartPanel 都会在看到随后的 ChartChangeEvent 时调度 repaint()

关于java - 添加新数据后更新 JFreeChart 绘图,MVC 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60147267/

相关文章:

java - 数据排序的最佳方式

ios - 手动实例化 ViewController 并推到顶部。好的做法?

java - JFreeChart 中的多线程

java - 找不到基本名称的 bundle

java - 运行 COMSOL Java API 时 Eclipse 中出现 UnsatisfiedLinkError

java - 两次 Java RPC 调用或一次

c++ - QTreeView 不显示标题

javascript - 如何使用 javascript 在我的 View 中重复特定的 C# 代码块,甚至应该这样做吗?

java - 类似于 Delphi 中的 JFreeChart

java - 如何在java中处理击键事件,但将其传递以使其具有 "natural"效果?