Reputation: 73
I'm currently trying to develop a class for Processing library developers that is supposed to allow them to access the PApplet generated by Processing. I already asked this question on the Processing with no one being able to provide a real solutions.
I eventually managed to come up with this code that seems to work just fine for the JAVA2D renderer. (If it's requested I will send this code)
However for the P2D and P3D renderers this code doesn't work. I found the following reason for that:
P2D and P3D use JOGL (Java OpenGL) and it defines it's window type from scratch making java.awt.Window.getWindows() not detect this window. If I were able to find that window I would already have a plan on finding the PApplet.
How can I find all active JOGL windows in a similar manner to java.awt.Window.getWindows()?
Edit: The link to the entry in the Processing Forum: https://discourse.processing.org/t/get-the-current-instance-of-papplet-from-a-library/36925
The code that only works with the JAVA2D renderer:
import processing.awt.*;
import processing.core.*;
import javax.swing.*;
import java.awt.*;
import java.lang.reflect.*;
/**This class finds the active PApplet (Processing program)*/
public class PAppletFinder{
/**This class takes the contents of the window and pieces together the PApplet
* @return PApplet of the current sketch.
* @param c contents of the Processing window (must be a SmoothCanvas)*/
public static PApplet get(Component c) {
PSurfaceAWT.SmoothCanvas sc=(PSurfaceAWT.SmoothCanvas) c;
try {
PSurfaceAWT psa=(PSurfaceAWT) get(sc,"this$0",sc.getClass());
PApplet prg=(PApplet) get((PSurfaceNone)psa,"sketch",PSurfaceNone.class);
return prg;
}
catch(Exception e) {
e.printStackTrace();
}
return null;
}
public static PApplet foundPapplet=null;
/**The main method to be used when using the PAppletFinder*/
public static PApplet find() {
if(foundPapplet==null) foundPapplet=findFromWindow();
return foundPapplet;
}
/**This looks out for windows and gives the contents of the right one to the get method
* @return PApplet of the current sketch.*/
public static PApplet findFromWindow() {
JFrame mainWindow=null;
java.awt.Window win[]=java.awt.Window.getWindows();
for (int i=0; i<win.length&&mainWindow==null; i++) if (win[i] instanceof JFrame) mainWindow=(JFrame) win[i];
Component c=mainWindow.getContentPane().getComponents()[0];
return get(c);
}
/**This is used to get the this$0 field of the SmoothCanvas
* Directly searching for the field didn't work. However for some reason
* looking through all the fields does the trick.
* @return Object value of a field
* @param j the Object from which the value is taken
* @param target name of the field*/
public static Object get(Object j,String target,Class<?> ref) {
Field[] field_=ref.getDeclaredFields();
for(int i=0;i<field_.length;i++) {
field_[i].setAccessible(true);
try {
if(field_[i].getName().equals(target)) return field_[i].get(j);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return null;
}
}
This code works only in JAVA2D as processing uses JOGL windows with any other renderer. JAVA2D however uses JFrames which are a subclass of java.awt.Window and are therefore found by Window.getWindows().
Upvotes: 1
Views: 111