Resize event for sketch without draw() loop

Hi there!

A few friends and me have been working on a small spreadsheet-like software program lately and of course, we made it resizeable by using surface.setResizable(true).
The thing of this software is that, because it’s basically just a spreadsheet, we’re not refreshing the screen 60 times a second like usual, because there is absolutely no need to.
We do this by putting a noLoop() at the end of the draw() function and calling loop() whenever the screen needs to be redrawn, like in onMousePressed.

The big problem here is that is doesn’t redraw the screen when the window is resized and there is no onWindowResized() event or something similar either that we could use.
I’ve googled for stuff like this, but I kept on finding things using a pre() function, but as that runs before the draw() function, that doesn’t work in our case, as the draw() function is hardly called at all.

Does anyone know if there is a (simple) way of going about solving this problem?

The big problem here is that is doesn’t redraw the screen when the window is resized

The following demo refreshes the window when it is resized on my system (Mac). Could you post code which fails and demonstrates the problem?

void setup(){
 size (320, 240);
 surface.setResizable(true); 
 noLoop();
}

void draw(){
 background(255);
 rect(10, 10, 100, 100);
}

I would make a boolean (for example “update”) that always on the end of draw is set on false. If any funktion will update the display, it must set update on true. The whole Part that update your display is in an if:

if(update) {
  background(255);
  //...
  
  update = false;
}

Also you make two variables pWidth and pHeight that are set to width and height on the end of draw.
At the start of draw you make another if:

if(pWidth != width || pHeight != height)
update = true;

whole code:

boolean update = true;

int pWidth, pHeight;

void setup() {
  surface.setSize(500, 500);
  surface.setResizeable(true);
  pWidth= width;
  pHeight = height;
  //...
}

void update() {
  if(pWidth != width || pHeight != height)
  update = true;
  
  if(update) {
    //Code for Display
    
    update = true;
  }
  
  pWidth = width;
  pHeight = height;
}

This is how we do it:


void setup() {
  size (320, 240);
  surface.setResizable(true);
}

void draw() {
  //every frame the background changes, so you can see when the screen refreshes
  background(random(255));
  grid();
  noLoop();
}

void mousePressed() {
  loop();
}

void grid() {
  stroke(0);
  for (int i = 0; i < width; i+=20) {
    line(i, 0, i, height);
  }
  for (int i = 0; i < height; i+=20) {
    line(0, i, width, i);
  }
}

This works like we want it to, but we need a kind of onScreenResized() function that, like mousePressed(), gets fired even if the draw() loop isn’t running.
Right now we have to click inside the sketch to make it update the screen, which isn’t that much of a hassle, and we can deal with this minor annoyance if there is no solution.

We’ve thought about doing this too, but ultimately decided against it, because of the fact that the draw() still runs every frame. We want absolutely nothing happening at all when the sketch is not being interacted with and a loop running 60 times a second is not nothing at all.
Maybe we could set the frameRate to 60 is the mouse is inside the sketch and to a really low number if it’s not, but that also kind of defeats the purpose.

What you’re looking to do is add a (renderer-dependent) stage/window resize callback listener, which should call Processing’s redraw() when prompted. See Resizable window with constrained proportions for FX2D and P2D examples.

1 Like

I was just doing that but it seems micycle already gave an answer :slight_smile:

import com.jogamp.newt.opengl.*;
import com.jogamp.newt.event.*;
class ResizeWindowListener implements WindowListener {
  public ResizeWindowListener() {
    super();
  }
  @Override
    public void windowGainedFocus(WindowEvent arg0) {
  }

  @Override
    public void windowLostFocus(WindowEvent arg0) {
  }

  @Override
    public void windowDestroyNotify(WindowEvent arg0) {
  }

  @Override
    public void windowDestroyed(WindowEvent arg0) {
  }

  @Override
    public void windowMoved(WindowEvent arg0) {
  }

  @Override
    public void windowRepaint(WindowUpdateEvent arg0) {
  }

  @Override
    public void windowResized(WindowEvent arg0) {
    println("resized!");
    loop();
  }
}
void setup() {
  size (320, 240, P2D);
  surface.setResizable(true);
  GLWindow f = (GLWindow)surface.getNative();
  ResizeWindowListener wl = new ResizeWindowListener();
  f.addWindowListener(wl);
}

void draw() {
  //every frame the background changes, so you can see when the screen refreshes
  grid();
  println("drawn!");
  noLoop();
}

int b = 0;
void grid() {
  background(b = (b+10)%255);
  stroke(0);
  for (int i = 0; i < width; i+=20) {
    line(i, 0, i, height);
  }
  for (int i = 0; i < height; i+=20) {
    line(0, i, width, i);
  }
}
2 Likes

That’s it! Thank you very much!!
There’s just a small problem now where the cursor doesn’t change into the expected different resize icon when hovering over the edge of the window. This seems to be a P2D problem related to surface.setResizable(true); (We’re on Windows, by the way)
I can find a few other posts related to this problem, but not a solution. Does that mean there isn’t one?