NumericPrime
NumericPrime

Reputation: 73

Finding all active JOGL (Java OpenGL) windows

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

Answers (0)

Related Questions