Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
270 views
in Technique[技术] by (71.8m points)

java - How can I bind stage width and height in JavaFX?

I want to bind the stage width and height together, so the user can only resize it by keeping the aspect ration.
This doesn't work:

stage.widthProperty().bind(stage.heightProperty());  

There is another way:

stage.minHeightProperty().bind(scene.widthProperty().multiply(1.3));  
stage.maxHeightProperty().bind(scene.widthProperty().multiply(1.3));  

But in this way I only set the width value.
How could I solve this?

Thanks,
Tibor

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since the width and height properties are read-only you cannot bind them to anything, let alone each other. The reason they're read-only is documented:

Many of the Stage properties are read only because they can be changed externally by the underlying platform and therefore must not be bindable [because bound properties cannot be set].

Both the width and height properties have similar statements in their documentation.

You can still add a listener to each property and, when one property changes, set the other property to the new value. To make sure this doesn't lead to a StackOverflowError you'll have to track if you're currently setting the value in the listener. For example:

// not actually "binding" in the context of Property.bind(...)
public static void bindWidthAndHeightTogether(Window window, double widthToHeightRatio) {
  ChangeListener<Number> listener =
      new ChangeListener<>() {

        private boolean changing;

        @Override
        public void changed(ObservableValue<? extends Number> obs, Number ov, Number nv) {
          if (!changing) {
            changing = true;
            try {
              if (obs == window.widthProperty()) {
                window.setHeight(nv.doubleValue() / widthToHeightRatio);
              } else {
                window.setWidth(nv.doubleValue() * widthToHeightRatio);
              }
            } finally {
              changing = false;
            }
          }
        }
      };
  window.widthProperty().addListener(listener);
  window.heightProperty().addListener(listener);
}

The above worked for me on Windows 10 using JavaFX 14. Note that it prevents the window from being maximized properly but not from going full-screen (at least on Windows 10).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...