I’ve done some digging – inspired by @GoToLoop and @quark – and have found a solution.
Closing sketches in P2D
and JAVA2D
renderer modes calls the PApplet instance’s exitActual()
method, which contains the line System.exit(0)
– a static method – which terminates the currently running Java virtual machine.
Overriding exitActual()
with nothing (i.e. preventing the call to System.exit(0)
) prevents sketches from closing others, fixing the issue, but introduces another problem in the case of P2D
sketches: the window is not disposed properly when the cross is clicked.
Solution:
Override exitActual()
to prevent the JVM (and all sketches) closing when one sketch is closed.
@Override
public void exitActual() {
}
Introduce the following code (suitable in setup()
) such that P2D
sketches are disposed properly:
if (getGraphics().isGL()) {
final com.jogamp.newt.Window w = (com.jogamp.newt.Window) getSurface().getNative();
w.setDefaultCloseOperation(WindowClosingMode.DISPOSE_ON_CLOSE);
}
However, in overriding (preventing) the call to System.exit(0)
, another issue is introduced: even after all sketches (windows) are closed, the JVM will continue to run in memory. Ideally System.exit(0)
should be called but only when the last remaining window is disposed.
I propose a rudimentary fix below – a simple counter – but I wonder whether it is possible to inspect the JVM to see the number of live instances of JavaFX/NEWT/AWT windows, using those values instead?
@Override
public void exitActual() {
if (Benchmark.n == 1) {
System.exit(0);
}
Benchmark.n--;
}
public class Benchmark {
public static int n = 3;
public static void main(String[] args) {
Sketch sketch1 = new Sketch(PApplet.FX2D);
Sketch sketch2 = new Sketch(PApplet.P2D);
Sketch sketch3 = new Sketch(PApplet.JAVA2D);
PApplet.runSketch(new String[] { "--location=760,0", "" }, sketch1);
PApplet.runSketch(new String[] { "--location=760,80", "" }, sketch2);
PApplet.runSketch(new String[] { "--location=760,160", "" }, sketch3);
}
}