Creating detached windows

You could pass it, but draw() doesn’t work in a JFrame. Would need to draw into a JPanel.

Just tried this basic code on my Linux box with PopOS:

I can’t even run a resizable window on my Linux system. No wonder the other demo won’t work!

Original demo runs ok on Windows11 and MacOS.

Hi! It should work, because for me it works. Processing needs to do something about that. :frowning:
-Libby

Please see if you can run this on your system. Note that different PGraphics images are passed to a single PApplet class along with other parameters. The square on each PApplet window is a PGraphics image constructed in the code for the default Processing window.

Addendum: Edited to improve code.

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

// **** Globals **** //
Window wnd1;
Window wnd2;
PGraphics pg1;
PGraphics pg2;

class Window extends PApplet {
  Frame frame;
  Canvas canvas;

  Point offset = new Point();

  int x, y, w, h;
  color bkgrnd;
  PGraphics inGraphics;

  public Window(int x, int y, int w, int h, color bkgrnd, PGraphics inGraphics) {
    // Needs to be here for use in settings(), setup(), and draw()
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.bkgrnd = bkgrnd;
    this.inGraphics = inGraphics;

    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
    frame = ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
    canvas = (processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative();  
    frame.removeNotify();
    frame.setUndecorated(true);
    frame.addNotify();
    frame.setLocation(x, y);
    
    canvas.addMouseListener(new MouseAdapter() {
      void mousePressed(MouseEvent msEvnt) {
        offset.x = msEvnt.getX();
        offset.y = msEvnt.getY();
      }
    }
    );

    canvas.addMouseMotionListener(new MouseMotionAdapter() {
      void mouseDragged(MouseEvent msEvnt) {
        Point pt = frame.getLocation();
        frame.setLocation(pt.x + msEvnt.getX() - offset.x, pt.y + msEvnt.getY() - offset.y);
      }
    }
    );
  }

  void settings() {
    size(w, h);
  }

  void setup() {
    background(bkgrnd);
    frame.setResizable(true);
  }

  void draw() {
    fill(0, 255, 0);
    circle(50, 50, 50);
    if(inGraphics != null){
     image(inGraphics, 150, 150);
    }
  }
}

// =========== Default Processing Window ========= //

void setup() {
  size(400, 400);
  surface.setTitle("Default Window");
  
  pg1 = createGraphics(100, 100);
  pg2 = createGraphics(150, 150);
  
  pg1.beginDraw();
  pg1.background(0, 255, 0);
  pg1.stroke(0);
  pg1.fill(244, 255, 0);
  pg1.circle(50, 50, 50);
  pg1.endDraw();

  pg2.beginDraw();
  pg2.background(102);
  pg2.stroke(255);
  pg2.line(pg2.width*0.5, pg2.height*0.5, mouseX, mouseY);
  pg2.endDraw();

  wnd1 = new Window(80, 150, 300, 400, color(0, 0, 255), pg1);
  wnd2 = new Window(700, 150, 400, 400, color(255, 255, 0), pg2);
}

void draw() {
  fill(255, 0, 0);
  circle(width/2, height/2, 200);
}

Output:

1 Like

Hello @svan,

Code in previous post(s) generated the following errors on W10 with Processing 4.3:

This seemed to solve the problem most of the time but not all of the time:

frame.createBufferStrategy(2);

Above insight was gleaned from various references searching for:
createBufferStrategy(2) (or related)

and I am only sharing this as an initial exploration of this error.

:)

Hi! This code as it is works 50% of the time, but does not work with OpenGL aka P2D.
-Libby

I’ve seen similar errors on Linux and also tried to createBufferStrategy(), but failed. The two offending lines of code are removeNotify() and setUndecorated(). Thanks for the feedback; now we have a good idea where the problem lies if we can just figure out how to fix it.

Addendum: Changed source code to create undecorated frame immediately after getting frame and canvas and added addNotify(). Also deleted the line to offset the canvas. Mouse handlers switched to canvas from frame; these changes appeared to markedly reduce error messages and will now run on Linux:

   PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
    frame = ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
    canvas = (processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative();  
    frame.removeNotify();
    frame.setUndecorated(true);
    frame.addNotify();
    frame.setLocation(x, y);

canvas.addMouseListener(new MouseAdapter() {...}

canvas.addMouseMotionListener(new MouseMotionAdapter() {...}

As a work around, do those auxillary windows have to be undecorated? Try REMMing out removingNotify() and setDecorated().

1 Like

This version has been behaving pretty well on a Linux operating system (PopOS). Please see how it runs on your system:

import java.awt.*;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

Window wnd;
Window wnd1;

class Window extends PApplet {
  Frame frame;
  Canvas canvas;

  Point offset = new Point();

  int x, y, w, h;
  color bkgrnd;

  public Window(int x, int y, int w, int h, color bkgrnd) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.bkgrnd = bkgrnd;

    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
    frame = ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
    canvas = (processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative();
    println(canvas);
    frame.removeNotify();
    frame.setUndecorated(true);
    frame.addNotify();
    frame.setLocation(x, y);
    // canvas.setLocation(0, 28);

    canvas.addMouseListener(new MouseAdapter() {
      void mousePressed(MouseEvent e) {
        offset.x = e.getX();
        offset.y = e.getY();
      }
    }
    );

    canvas.addMouseMotionListener(new MouseMotionAdapter() {
      void mouseDragged(MouseEvent e) {
        Point pt = frame.getLocation();
        frame.setLocation(pt.x + e.getX() - offset.x, pt.y + e.getY() - offset.y);
      }
    }
    );
  }

  void settings() { // Necessary for PApplet
    println(w, h);
    size(w, h);  // Sets canvas size
  }

  void setup() {
    background(bkgrnd);
    frame.setResizable(true);
  }

  void draw() {
    fill(0, 255, 0);
    rect(30, 50, 100, 30, 15);
    fill(0); // text color
    textSize(22.0);
    textAlign(CENTER, CENTER);
    text("myBtn", 30, 50, 100, 30);
  }

  void mousePressed() {
    if ((mouseX >= 30) && (mouseX <= 30 + 100) && (mouseY >= 50) && (mouseY <= 50 + 30)) {
      println("button hit.");
    }
  }
}

// **** Default Window **** //

void setup() {
  size(800, 800);
  surface.setTitle("Default Window");
  wnd = new Window(100, 100, 400, 400, color(255, 255, 0));
  wnd1 = new Window(600, 100, 600, 600, color(0, 0, 255));
}

void draw() {
  fill(255, 0, 0);
  circle(width/2, height/2, 200);
}

void mousePressed() {
  println("mousePressed in default window");
}

Output:

Hi! :slight_smile: It all works now 90% of the time.

I change the code so if you press the mouse down, it creates a new window:
import java.awt.*;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;

Window wnd;
Window wnd1;

class Window extends PApplet {
  Frame frame;
  Canvas canvas;

  Point offset = new Point();

  int x, y, w, h;
  color bkgrnd;

  public Window(int x, int y, int w, int h, color bkgrnd) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.bkgrnd = bkgrnd;

    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
    frame = ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
    canvas = (processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative();
    println(canvas);
    frame.removeNotify();
    frame.setUndecorated(true);
    frame.addNotify();
    frame.setLocation(x, y);
    // canvas.setLocation(0, 28);

    canvas.addMouseListener(new MouseAdapter() {
      void mousePressed(MouseEvent e) {
        offset.x = e.getX();
        offset.y = e.getY();
      }
    }
    );

    canvas.addMouseMotionListener(new MouseMotionAdapter() {
      void mouseDragged(MouseEvent e) {
        Point pt = frame.getLocation();
        frame.setLocation(pt.x + e.getX() - offset.x, pt.y + e.getY() - offset.y);
      }
    }
    );
  }

  void settings() { // Necessary for PApplet
    println(w, h);
    size(w, h);  // Sets canvas size
  }

  void setup() {
    background(bkgrnd);
    rect(10, 10, 100, 100);
    frame.setResizable(true);
  }

  void draw() {
    fill(0, 255, 0);
    rect(30, 50, 100, 30, 5);
    fill(0); // text color
    textSize(22.0);
    textAlign(CENTER, CENTER);
    text("myBtn", 30, 50, 100, 30);
  }

  void mousePressed() {
    if ((mouseX >= 30) && (mouseX <= 30 + 100) && (mouseY >= 50) && (mouseY <= 50 + 30)) {
      println("button hit.");
    }
  }
}

// **** Default Window **** //

void setup() {
  size(800, 800, P2D);
  surface.setTitle("Default Window");
}

void makeWindow() {
  try {
    wnd = new Window(100, 100, 400, 400, color(255, 255, 0));
    wnd1 = new Window(600, 100, 600, 600, color(0, 0, 255));
  } catch (IllegalStateException e) {
    print("Trying again...");
    makeWindow();
  }
}

void draw() {
  background(255);
  fill(255, 0, 0);
  circle(width/2, height/2, dist(width/2, height/2, mouseX, mouseY));
}

void mousePressed() {
  makeWindow();
  println("mousePressed in default window");
}

This works like 5 times, then it crashes. I tried building a try catcher for error handling, but that doesn’t seem to do anything!
Thanks for your patience!
-Libby

May be running out of memory to maintain all those windows.

1 Like

Code from here:
https://discourse.processing.org/t/creating-detached-windows/42987/30

This shows up in console content (no red status in console bar) around 50% of time in W10 Processing 4.3:

It really doesn’t like that undecorated frame. I don’t recall seeing that on Windows11. When you state that there was no red status in console bar does that mean that the window is formed ok and it’s more of a warning or is the window not formed and it’s more of an exception? If you can’t use the window 50% of the time that’s a problem. I thought that rearranging the code had fixed it, but apparently not on Windows 10. The only way to really solve this is to figure out BufferStrategy and save that before undecorating the frame; so far I haven’t been able to do that. Thanks for the feedback; always appreciated.

Just to verify the above, the following code should run without error on Windows 10:

import java.awt.*;

Window wnd;

class Window extends PApplet {
  Frame frame;
  Canvas canvas;

  int x, y, w, h;
  color bkgrnd;
  
  public Window(int x, int y, int w, int h, color bkgrnd) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.bkgrnd = bkgrnd;
    
    PApplet.runSketch(new String[] {this.getClass().getSimpleName()}, this);
    frame = ((processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative()).getFrame();
    canvas = (processing.awt.PSurfaceAWT.SmoothCanvas) surface.getNative();

    frame.setLocation(x,y);
    println(canvas);
        
  }

  void settings() { // Necessary for PApplet
    size(w, h);  // Sets canvas size
  }

  void setup() {
    background(bkgrnd);
    surface.setResizable(true);
  }

  void draw() {
    fill(0, 255, 0);
    rect(30, 50, 100, 30);
    fill(0);
    textSize(18.0);
    textAlign(CENTER, CENTER);
    text("MyBtn", 30, 50-2, 100, 30);
  }

  void mousePressed() {
    if ((mouseX >= 30) && (mouseX <= 30 + 100) && (mouseY >= 50) && (mouseY <= 50 + 30)) {
      println("button hit.");
    }
  }
}

// **** Default Window **** //

void setup() { 
  size(400, 400);
  surface.setTitle("Default Window");
  wnd = new Window(100, 100, 300, 300, color(0));
}

void draw() {
  fill(255, 0, 0);
  circle(width/2, height/2, 200);
}

void mousePressed() {
  println("mousePressed in default window");
}

Hi! To be honest, i think processing doesn’t like undecorated windows at all! They need to fix that, maybe add some prebuilt functions that are also well documented for creating more complexx applications. It would be really nice!
-Libby!

Thank you for this code!
For me this code is completly fine. This code works good on linux too and i can use the Processing Open Gl renderer wich makes me very happy as i can continue to create cool apps. Processing made me really happy so far even with the controversy (Ben fry).
-Libby