The following problem can be reproduced in Linux VMs (RHEL/CentOS/Ubuntu) or a real Linux system using various versions of mesa drivers, but not reproduced on Windows 10/11 using Intel/NVidia drivers.
(1) minimize the 3D window
(2) deiconify the 3D window --> the JCanvas3D window randomly crashes (with probability > 90%), but Canvas3D always works.
JCanvas3D performs better than Canvas3D regarding the flickering issue, so the use of JCanvas3D is desired in our case.
Similar reports (solved by upgrading the driver to the one provided by NVIDIA):
3D Display crashes when switching between 3d display and other displays in Linux
https://sourceforge.net/p/repast/mailman/message/37199523/(JCanvas3D is used in Display3D of repast.simphony)
After some debugging, it seems that if we commented out the lines in ancestorMoved in JCanvas3D the crash disappears.
JCanvas3D.java:
@Override
public void ancestorRemoved(javax.swing.event.AncestorEvent event) {
//hasBeenAdded = false;
//canvas.removeNotify();
}
The AncestorEvent is fired when the ancestor becomes visible/invisible, so it is fired when the 3D window is created, iconified/deiconifed, or disposed. As an intuition, if the 3D window is just iconified/deiconified, there is no need to call canvas.removeNotify()/canvas.addNotify(). Therefore, it is desired to identify the reason of the AncestorEvent, whether the 3D window is iconified/deiconified, or created/disposed.
I wonder if this can be achieved by passing the parent (JFrame or JInternalFrame) to JCanvas and do something for that.