# G4P/grafica multiwindow plot crash

**URL:** <https://discourse.processing.org/t/g4p-grafica-multiwindow-plot-crash/18440>\
**Category:** Electronics (Arduino, etc.)\
**Created:** [March 6, 2020, 8:55am UTC](https://discourse.processing.org/t/g4p-grafica-multiwindow-plot-crash/18440 "2020-03-06T08:55:30Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cannocchiale](https://avatars.discourse-cdn.com/v4/letter/c/e56c9b/32.png) [@cannocchiale](https://discourse.processing.org/u/cannocchiale)\
**Post date:** [March 6, 2020, 8:55am UTC](https://discourse.processing.org/t/g4p-grafica-multiwindow-plot-crash/18440/1 "2020-03-06T08:55:30Z")

</div>

Hello everyone,

I’m having a stability issue when using **G4P** and **grafica** libraries. I want to create a program which reads a serial string sent by arduino. It is a two-channel pressure measurements - an E and an F channel. I built a GUI that shows in two windows the real-time plots of pressure against time measurements.

While the code compiles and runs, after a while (20/30 seconds circa) it starts giving some Errors - without crashing:

ERROR 1:

> ################ EXCEPTION IN EVENT HANDLER ################  
> An error occured during execution of the eventhandler:  
> CLASS: Lilliput\_GUI\_2 METHOD: win\_drawE  
> Caused by java.lang.IndexOutOfBoundsException: Index: 522, Size: 676  
> java.util.ArrayList.rangeCheck(ArrayList.java:657)  
> java.util.ArrayList.get(ArrayList.java:433)  
> grafica.GLayer.drawPoints(Unknown Source)  
> grafica.GPlot.drawPoints(Unknown Source)  
> Lilliput\_GUI\_2.win\_drawE(Lilliput\_GUI\_2.java:272)  
> sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)  
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
> java.lang.reflect.Method.invoke(Method.java:498)  
> g4p\_controls.GWindow.draw(Unknown Source)  
> g4p\_controls.GWindowAWT.draw(Unknown Source)  
> sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)  
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
> java.lang.reflect.Method.invoke(Method.java:498)  
> processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1411)  
> processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1404)  
> processing.core.PApplet.handleMethods(PApplet.java:1603)  
> processing.core.PApplet.handleDraw(PApplet.java:2442)  
> processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557)  
> processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)  
> ##############################################################

After a relatively long period (700 seconds circa, a totally insufficient period for my purposes), the program stops plotting on the windows (not at the same time) without crashing, giving the errors

> ################ EXCEPTION IN EVENT HANDLER ################  
> An error occured during execution of the eventhandler:  
> CLASS: Lilliput\_GUI\_2 METHOD: win\_drawE  
> Caused by java.lang.IndexOutOfBoundsException: Index: 558, Size: 698  
> java.util.ArrayList.rangeCheck(ArrayList.java:657)  
> java.util.ArrayList.get(ArrayList.java:433)  
> grafica.GLayer.drawPoints(Unknown Source)  
> grafica.GPlot.drawPoints(Unknown Source)  
> Lilliput\_GUI\_2.win\_drawE(Lilliput\_GUI\_2.java:272)  
> sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)  
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
> java.lang.reflect.Method.invoke(Method.java:498)  
> g4p\_controls.GWindow.draw(Unknown Source)  
> g4p\_controls.GWindowAWT.draw(Unknown Source)  
> processing.core.PApplet.handleDraw(PApplet.java:2429)  
> processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557)  
> processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)  
> ##############################################################
> 
> ################ EXCEPTION IN EVENT HANDLER ################  
> An error occured during execution of the eventhandler:  
> CLASS: Lilliput\_GUI\_2 METHOD: win\_drawE  
> Caused by java.lang.RuntimeException: pushMatrix() cannot use push more than 32 times  
> processing.awt.PGraphicsJava2D.pushMatrix(PGraphicsJava2D.java:2144)  
> processing.core.PApplet.pushMatrix(PApplet.java:13193)  
> grafica.GAxis.drawAsYAxis(Unknown Source)  
> grafica.GAxis.draw(Unknown Source)  
> grafica.GPlot.drawYAxis(Unknown Source)  
> Lilliput\_GUI\_2.win\_drawE(Lilliput\_GUI\_2.java:270)  
> sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)  
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  
> java.lang.reflect.Method.invoke(Method.java:498)  
> g4p\_controls.GWindow.draw(Unknown Source)  
> g4p\_controls.GWindowAWT.draw(Unknown Source)  
> processing.core.PApplet.handleDraw(PApplet.java:2429)  
> processing.awt.PSurfaceAWT$12.callDraw(PSurfaceAWT.java:1557)  
> processing.core.PSurfaceNone$AnimationThread.run(PSurfaceNone.java:313)  
> ##############################################################

repeatedly.

I still have to figure out what’s going wrong, but I think it is related on how G4P handles the plot creation. Also because I haven’t used pushMatrix() method anywhere in the code.

[Link to code](https://codepen.io/ifidamas/pen/RwPjbjR?editors=1000);  
[Link to GUI](https://codepen.io/ifidamas/pen/XWbzrzG?editors=1000);

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [March 6, 2020, 10:04am UTC](https://discourse.processing.org/t/g4p-grafica-multiwindow-plot-crash/18440/2 "2020-03-06T10:04:34Z")

</div>

All these errors are occurring _ **inside** _ the draw method for the second window `win_drawE` so is not necessarily as a result of G4P. The trick here is to read and understand the stack trace.

So we will start with the first one and what we are looking for is not where the exception is _thrown_ but the _ **cause** _ of the exception and if we look at the trace we can see this in line 4.

1. ################ EXCEPTION IN EVENT HANDLER ################
2. An error occured during execution of the eventhandler:
3. CLASS: Lilliput\_GUI\_2 METHOD: win\_drawE
4. Caused by java.lang.IndexOutOfBoundsException: Index: 522, Size: 676
5. java.util.ArrayList.rangeCheck(ArrayList.java:657)
6. java.util.ArrayList.get(ArrayList.java:433)
7. grafica.GLayer.drawPoints(Unknown Source)
8. grafica.GPlot.drawPoints(Unknown Source)
9. Lilliput\_GUI\_2.win\_drawE(Lilliput\_GUI\_2.java:272)
10. sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
11. …

So the error is caused by an `IndexOutOfBoundsException` thrown by the `java.util.ArrayList.rangeCheck` method.

If we look at the next line (6) we can see that the program attempted to use the `ArrayList get(int)` method. So the problem is that the index value passed to the `get` method is \< 0 or \>= arraylist size. So when did this happen? Look at the next line (7) the error occurred in the Grafica library library, specifically in the `drawPoints()` method of the `GLayer` class.

If we look at the other traces all the problems appear to be in the graphica library rather than G4P.

One final point, each GWindow has its own event-handling thread so you need to be careful when using shared data e…g. the `plot[]` array it might be part of the problem.

---

<div class="post-metadata">

**Author:** ![cannocchiale](https://avatars.discourse-cdn.com/v4/letter/c/e56c9b/32.png) [@cannocchiale](https://discourse.processing.org/u/cannocchiale)\
**Post date:** [March 6, 2020, 10:37am UTC](https://discourse.processing.org/t/g4p-grafica-multiwindow-plot-crash/18440/3 "2020-03-06T10:37:18Z")

</div>

Thank you very much for your reply.

So what do you think is the problem?  
The fact is that I have to add points to plot[i] dynamically any time the serial arduino port is available and fetches data; hence I use plot[i] - which is an array of GPlot - and add to them the datapoints, via the _plot[i].add_ method.

Now, I want the plot to be shown in the two windows “pressioneE” and “pressioneF” and this is why I call the _plot[i].beginDraw()_ (etc) method inside the win\_drawE function;

There is a more suitable way to real-time plot a function-scoped variable that reads the datapoints from the global-scoped plot[i] GPlot object?

Also, the plot stop working when _the pushMatrix()_ error kicks in. Is that problem related to this one (let us say, a consequence)?

Do you suggest to modify (or re-post) this thread to a “Grafica multiwindow plot crash”?

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [March 6, 2020, 2:00pm UTC](https://discourse.processing.org/t/g4p-grafica-multiwindow-plot-crash/18440/4 "2020-03-06T14:00:27Z")

</div>

> [@cannocchiale](#):
>
> Do you suggest to modify (or re-post) this thread to a “Grafica multiwindow plot crash”?

I would rename this thread **Graphica / G4P mult window crash** do not re-post.

I have not looked at the Graphica library for a very long time so there will be changes that I am not familiar with. If you seriously want my help then I would need to experiment with the sketch code so you would need to send the sketch to me.

I will send you a PM with my email address, and if you want me to look at it then archive the sketch ( **Tools \>\> Archive Sketch** menu option) and send the zip file to me by email.

Before you do that make sure you are using the latest versions Processing, G4P and Graphica.

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [March 6, 2020, 3:36pm UTC](https://discourse.processing.org/t/g4p-grafica-multiwindow-plot-crash/18440/5 "2020-03-06T15:36:43Z")

</div>

> [@cannocchiale](#):
>
> ; hence I use plot[i] - which is an array of GPlot - and add to them the datapoints, via the _plot[i].add_ method.

- There’s no GPlot method exactly named **add()** but 1s that start w/ “add”.
- Much probably you’re using method **addLayer()**.
- When you do so, you’re increasing the **size()** of the GPlot’s internal ArrayList.
- The library grafica, as the majority of Processing’s 3rd-party libraries, is single-threaded only.
- That is, it lacks mechanisms to deal w/ multithreading access.
- So you should never invoke GPlot::**addLayer()** outside the PApplet’s Thread it is bound to!
- Actually, most of grafica’s API is dangerous to access from other threads.
- As a workaround you can collect the Arduino’s received data to some global container.
- Then once inside the GPlot’s Thread code, invoke GPlot::**addLayer()** there, passing the container’s items as its argument.

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [March 9, 2020, 8:59pm UTC](https://discourse.processing.org/t/g4p-grafica-multiwindow-plot-crash/18440/6 "2020-03-09T20:59:52Z")

</div>

OK I have had a look at your sketch and the problem is caused by having multiple windows sharing data.

The solution is too use a Java concurrent collection. The other problem was your code is not extensible and the code logic was difficult to understand. Although you have programming experience it is very limited with Java so it would be very time consuming to try and take you through the process of creating a fully extensible solution so I have done it for you.

The link below will download an archived sketch (zip file) simply unzip it and put it inside your sketch folder.

The sketch has 2 java tabs for the top level classes `PressureMonitor` and `Serial`. The Serial class simply simulates the connection to an Arduino device and in the finished product simply delete or better still comment out all the code in this class and import Processing’s Serial class instead. Inside the serial class the `serialProcess()` method produces dummy data for each channel.

The PressureMonitor encapsulates everything needed to graph a single channel

- a window
- a `LinkedBlockingQueue` (thread safe) to cache pressure data
- a table for the data
- a graphic plot
- a checkbox to ignore data for plotting
- a button to save the data as a csv file.

To add another channel simply add an identifier to this list in main pde tab

```auto
// ===========================================================
// To create more monitors simply add their unique ID here and
// modify the method 'serialProcess' in the Serial class
String[] channel_ids = new String[] { "E", "F" };
// ===========================================================

```

and modify the `serialProcess()` method to produce data for the new channel.

I have had the sketch running for 30 minutes now without any problems.

I think the time needed to produce an initial version for yourselves would be better spent studying and modifying this sketch to meet your needs.

Download the [sketch](http://www.lagers.org.uk/zzz/PressureGrapher-200309a.zip)

If you have any questions about using it just ask.

---

<div class="post-metadata">

**Author:** ![cannocchiale](https://avatars.discourse-cdn.com/v4/letter/c/e56c9b/32.png) [@cannocchiale](https://discourse.processing.org/u/cannocchiale)\
**Post date:** [March 10, 2020, 10:10am UTC](https://discourse.processing.org/t/g4p-grafica-multiwindow-plot-crash/18440/7 "2020-03-10T10:10:30Z")

</div>

Thank you A LOT for the suggestions and for the code.  
I’ve been running it for 2 hours now, and no error has appeared yet.  
I am very sorry for the messy code, but you are right, we have a very basic Java experience.

Unfortunately I cannot try the code at work, since we are in the “red zone” due to the coronavirus, but I will let you know if everything is ok when I will be able to test it at work again.

Thank you again!!
