I have made a project that involves reading data from a serial line and representing it on a graph. So far, I've had my serial reader class do a .validate() on the dataset contained in my grapher class. The SerialReader class just got passed the whole grapher object and made changes directly to it. It also had to update a set of labels. That method worked.
The problem with this was that the logic was updating the model, which was stored in the GUI object. Since I'm making many new functions to the program, reading more serial lines for different types of data, and even controlling some hydraulics. So I needed more of a separated, modular approach.
I now have Main start an instance of Grapher, the GUI class, which when started with a button, makes a StrainTestObject and starts a SerialReader thread. The former is passed to the latter, and the StrainTestObject class holds my series and dataset, along with other metadata. When these are all created, I load the dataset from the StrainTestObject into the GUI with a getter.
When I do it this way, the data is correctly added to the dataset, but the graph on the GUI doesn't update! I think the source of my problem then is that Java is pass-by-value, and so it won't get updated. What's an elegant solution to this? Is there some way to keep the serial reader process separate from the model, and from the GUI? Also, bonus question, what is the most resource-effective way of redrawing the graph with JFreeGraph, it starts to go real slow after a while on a Raspberry Pi.
Here's the relevant code from the Grapher class:
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()));
}
Here's the relevant code from the StrainTestObject class:
void addDataToGraph(double val) throws InvalidObjectException {
invokeLater(() -> {
series.add(new Millisecond(), val);
});
}
From constructor
series = new TimeSeries("Strekk");
dataset = new TimeSeriesCollection();
dataset.addSeries(series);
Now, if I alter the code to make series and dataset directly in the grapher class, and make SerialReader access it directly, it works fine. But it doesn't if it's kept in the StrainTestObject class.