# Resizable window with constrained proportions

**URL:** <https://discourse.processing.org/t/resizable-window-with-constrained-proportions/7536>\
**Category:** Coding Questions\
**Created:** [January 15, 2019, 11:52am UTC](https://discourse.processing.org/t/resizable-window-with-constrained-proportions/7536 "2019-01-15T11:52:24Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sarah](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sarah/32/1675_2.png) [@Sarah](https://discourse.processing.org/u/Sarah)\
**Post date:** [January 15, 2019, 11:52am UTC](https://discourse.processing.org/t/resizable-window-with-constrained-proportions/7536/1 "2019-01-15T11:52:24Z")

</div>

When I need the canvas to be resizable I use `surface.setResizable(true);`. However, I need to keep the width and height equal and can’t seem to find a way to apply constraints to do so.

I initially tried to manually set the size to keep the dimensions proportional, but that led to unpleasant flickering when I resized the window.

Any ideas on the best way to implement this are welcome.  
Thanks!

---

<div class="post-metadata">

**Author:** ![micycle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micycle/32/201_2.png) [@micycle](https://discourse.processing.org/u/micycle)\
**Post date:** [January 15, 2019, 12:05pm UTC](https://discourse.processing.org/t/resizable-window-with-constrained-proportions/7536/2 "2019-01-15T12:05:14Z")

</div>

In **FX2D** mode:

```
public void setup() {

	stage = (Stage) ((Canvas) surface.getNative()).getScene().getWindow();

	stage.widthProperty().addListener(new ChangeListener<Number>() {
		@Override
		public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
			stage.setHeight((double) newValue);
		}
	});

	stage.heightProperty().addListener(new ChangeListener<Number>() {
		@Override
		public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
			stage.setWidth((double) newValue);
		}
	});
}
```

---

<div class="post-metadata">

**Author:** ![Sarah](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sarah/32/1675_2.png) [@Sarah](https://discourse.processing.org/u/Sarah)\
**Post date:** [January 15, 2019, 12:28pm UTC](https://discourse.processing.org/t/resizable-window-with-constrained-proportions/7536/3 "2019-01-15T12:28:19Z")

</div>

Unfortunately, I’m currently working in a P3D environment, so this solution isn’t what I currently need. I’m looking for a more universal solution, but it seems that wouldn’t be realistic.

Also, I’ve tested the code and gotten an error: _Cannot refer to the non-final local variable stage defined in an enclosing scope_ from `stage.setHeight((double) newValue);`. Any idea on how to fix it?

Thanks for you quick reply!

---

<div class="post-metadata">

**Author:** ![micycle](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/micycle/32/201_2.png) [@micycle](https://discourse.processing.org/u/micycle)\
**Post date:** [January 15, 2019, 1:06pm UTC](https://discourse.processing.org/t/resizable-window-with-constrained-proportions/7536/4 "2019-01-15T13:06:33Z")

</div>

I’m not certain, although it could be something to do with working in the Processing IDE, or lacking (some of) the following imports:

```auto
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.canvas.Canvas;
import javafx.stage.Stage;

```

---

<div class="post-metadata">

**Author:** ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)\
**Post date:** [January 15, 2019, 7:07pm UTC](https://discourse.processing.org/t/resizable-window-with-constrained-proportions/7536/5 "2019-01-15T19:07:33Z")

</div>

> [@Sarah](#):
>
> _Cannot refer to the non-final local variable stage defined in an enclosing scope_ from `stage.setHeight((double) newValue);`.

We can always use keyword `final` in Java for almost anything. I use it all the time in my own sketches! 🙃

> **[final / Reference](https://processing.org/reference/final.html)**
>
> Keyword used to state that a value, class, or method can't be changed. If the final keyword is used to define a variable, the variable can't be changed within the program. When used to define a…

`final Stage stage = (Stage) ((Canvas) surface.getNative()).getScene().getWindow();`

---

<div class="post-metadata">

**Author:** ![Sarah](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sarah/32/1675_2.png) [@Sarah](https://discourse.processing.org/u/Sarah)\
**Post date:** [January 15, 2019, 10:27pm UTC](https://discourse.processing.org/t/resizable-window-with-constrained-proportions/7536/6 "2019-01-15T22:27:41Z")

</div>

Thanks, that worked! I’ll try to look into P3D and see if I can get something working.

---

<div class="post-metadata">

**Author:** ![Sarah](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sarah/32/1675_2.png) [@Sarah](https://discourse.processing.org/u/Sarah)\
**Post date:** [January 16, 2019, 9:03am UTC](https://discourse.processing.org/t/resizable-window-with-constrained-proportions/7536/7 "2019-01-16T09:03:56Z")

</div>

I’ve made a listener for P3D which works most of the time:

```auto
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowUpdateEvent;

GLWindow window;

int pWidth;
int pHeight;

WindowListener windowListener = new WindowListener() {
  void windowDestroyed(WindowEvent e) {
  }
  void windowDestroyNotify(WindowEvent e) {
  }
  void windowGainedFocus(WindowEvent e) {
  }
  void windowLostFocus(WindowEvent e) {
  }
  void windowMoved(WindowEvent e) {
  }
  void windowRepaint(WindowUpdateEvent e) {
  }
  void windowResized(WindowEvent e) {
    int newSize = window.getWidth();
    if (window.getWidth() != pWidth) { 
      newSize = window.getWidth();
    }
    if (window.getHeight() != pHeight) {
      newSize = window.getHeight();
    }
    window.setSize(newSize, newSize);
    pWidth = window.getWidth();
    pHeight = window.getHeight();
  }
};

void setup() {
  size(100, 100, P3D);
  pWidth = width;
  pHeight = height;
  surface.setResizable(true);
  window = (GLWindow) surface.getNative();
  window.addWindowListener(windowListener);
}

```

But since it still has some issues, I think I might just stick with `surface.setSize();` for now.
