Multiple windows with Processing 3 ? ? ?

I hope to be able to update G4P for Processing 3. One of the key features of G4P was the ability to create apps with multiple windows. This was straightforward with PS2 because Applet inherited from PApplet, a windowed component.

I have been looking through PS source code but I have not found an obvious way of doing this.

Any hints or ideas gratefully received.

Thanks

Comments

  • edited August 2015

    Already tipped you about it before... Have you looked at runSketch() already?
    It exists since Processing 1. And "ignites" any PApplet instance w/ its own "canvas" + "Animation" Thread.

    http://forum.Processing.org/two/discussions/tagged?Tag=papplet.runsketch()

  • This just came up on StackOverflow earlier today: http://stackoverflow.com/questions/32243316/new-window-in-processing

    Here's my slightly hackish answer:

    void setup() {
      size(100, 100);
    
      String[] args = {"YourSketchNameHere"};
      SecondApplet sa = new SecondApplet();
      PApplet.runSketch(args, sa);
    }
    
    void draw() {
      background(0);
      ellipse(50, 50, 10, 10);
    }     
    
    public class SecondApplet extends PApplet {
    
      public void settings() {
        size(200, 100);
      }
      public void draw() {
        background(255);
        fill(0);
        ellipse(100, 50, 10, 10);
      }
    }
    

    This works for me, but I'm not sure how stable it is.

  • @GoToLoop sorry about that, forgot you mentioned it earlier

    @KevinWorkman thanks for the example of using runSketch

    This is brilliant I can see there will be other issues such as setting the frame name (Java mode) but it is a good start.

    Thanks guys

  • edited August 2015

    You can still get to the frame variable, as discussed here: http://forum.processing.org/two/discussion/12260/processing-3-init-disappearance#latest

    But you probably don't need to do that. Just go through the new surface variable:

    surface.setTitle("Your Title Here");

  • edited August 2015

    For backwards compatibility, you can make frame field an alias for surface or vice-versa. O:-)

  • Thanks again guys.

  • edited August 2015

    For backwards compatibility, you can make frame field an alias for surface or vice-versa.

    No, you can't. The surface variable is of type processing.core.PSurface. The frame variable is of type java.awt.Frame. They are incompatible types, since they don't share an inheritance, so they can't be assigned to one another.

  • edited August 2015

    Backwards compatability will not be possible because the differences between PS2 & PS3 are too great.

    Yesterday I released G4P V3.5.4 as the last version compatible for PS 2.2.1 all future releases will target PS3

  • edited August 2015
    // forum.processing.org/two/discussion/12272/multiple-windows-with-processing-3
    // GoToLoop (2015-Aug-29)
    
    void setup() {
      size(300, 200, JAVA2D);
      noLoop();
    
      Class<?> c = getClass();
      java.lang.reflect.Field f;
    
      try {
        f = c.getSuperclass().getDeclaredField("surface");
      }  
      catch (NoSuchFieldException e) {
        try {
          f = c.getField("frame");
        }
        catch (NoSuchFieldException ex) {
          throw new RuntimeException(ex);
        }
      }
    
      Object o;
    
      try {
        o = f.get(this);
      }
      catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      }
    
      java.lang.reflect.Method setTitle;
    
      try {
        setTitle = f.getType().getMethod("setTitle", String.class);
      }
      catch (NoSuchMethodException e) {
        throw new RuntimeException(e);
      }
    
      try {
        setTitle.invoke(o, "Working!");
      }
      catch (IllegalAccessException e) {
        throw new RuntimeException(e);
      }
      catch (java.lang.reflect.InvocationTargetException e) {
        throw new RuntimeException(e);
      }
      catch (IllegalArgumentException e) {
        throw new RuntimeException(e);
      }
    }
    
  • edited August 2015

    I'm not sure what you're trying to prove with that code, but that's a horrible misuse of reflection- and it won't work with Processing.js at all.

    That code does not create an alias between surface and frame. It simply calls frame.setTitle(), which you can (and should) just do directly:

    void setup() {     
      frame.setTitle("123 abc");
    }
    

    Or better yet, just go through the surface variable like you're supposed to:

    void setup() {
      surface.setTitle("abc 123");
    }
    

    If you think your code is doing something useful, please post an explanation. I'm still learning how Processing 3 fits together, so I'd love to learn more about it.

  • edited August 2015
    • I haven't installed Processing 3 till few minutes ago.
    • I was just assuming Processing 3 removed field frame and replaced it w/ surface.
    • After installing 3.0b5, it's turned out field frame still exists inside PApplet class!
    • Although they anonymously instantiated Frame class in such a way it invokes deprecationWarning("") for each of its methods. Exhorting us to use surface field instead: X(
      https://GitHub.com/processing/processing/blob/master/core/src/processing/core/PApplet.java#L10313
    • But the real problem is that they've declared field surface protected.
    • Therefore a simple getClass().getField("surface"); fails! :-&
    • I had to replace that w/ getClass().getSuperclass().getDeclaredField("surface"); instead. 3:-O

    P.S.: Actually what's stored in Processing 3's frame field is a fake Frame class; not the true java.awt.Frame or javax.swing.JFrame 1s! ~:>

  • edited August 2015

    If you think your code is doing something useful, please post an explanation.

    If it wasn't clear enough, I'm just trying to prove we can make some code dynamically choose either frame or surface fields depending on Processing's version it's running upon!

    Therefore, it's entirely possible for @quark to make newer versions of his G4P library to run both on Processing 2 & 3. Perhaps even on Processing 1! O:-)

    The example I've posted above runs in any Processing version.
    And invoke()s method setTitle() either over a processing.core.PSurface or a java.awt.Frame object! \m/

  • edited August 2015

    ... but that's a horrible misuse of reflection... and it won't work with Processing.js at all.

    Dunno why you've brought pjs framework as an issue here! 8-|
    G4P library isn't cross-mode & neither JS language needs any "reflection" techniques! [-(
    And if that's indeed a "reflection" misuse, can you tell us how to do all of that w/o it? :O)

  • edited August 2015

    A slightly shorter variant relying on isAssignableFrom() in order to determine which Field to get: :D

    // forum.processing.org/two/discussion/12272/multiple-windows-with-processing-3
    // GoToLoop (2015-Aug-29)
    
    size(300, 200, JAVA2D);
    noLoop();
    
    Class<?> t; // either PSurface or JFrame class.
    Object o;   // either PSurface or JFrame object.
    java.lang.reflect.Method setTitle; // setTitle() method.
    
    try {
      Class<PApplet> p = PApplet.class;
      Class<java.applet.Applet> a = java.applet.Applet.class;
    
      java.lang.reflect.Field f =
        p.getDeclaredField(a.isAssignableFrom(p)? "frame" : "surface");
    
      t = f.getType();
      o = f.get(this);
    }
    catch (ReflectiveOperationException e) {
      throw new RuntimeException(e);
    }
    
    try {
      setTitle = t.getMethod("setTitle", String.class);
    }
    catch (NoSuchMethodException e) {
      throw new RuntimeException(e);
    }
    
    try {
      setTitle.invoke(o, "Working!");
    }
    catch (ReflectiveOperationException e) {
      throw new RuntimeException(e);
    }
    
  • Therefore, it's entirely possible for quark to make newer versions of his G4P library to nrun both on Processing 2 & 3. Perhaps even on Processing 1!

    Sorry that is a totaly unrealistic expectation.

    Although from the users perspective G4P looks the same thats only because the API changes little between versions of Processing. G4P hooks into Processings inner workings so there is not a chance in hell of getting a single version of G4P to work on both PS2 & PS3, just as there was no chance with PS1 & PS2

Sign In or Register to comment.