9

I have been trying to set the scene's width and height outside of the constructor and it's been to no avail. After looking through the Scene API I saw a method that lets you get the height and width respectively but not one to set the method.. :s (design flaw maybe).

After further research I came across the SceneBuilder and found methods that could modify the height and width. However, I do not know how to apply it to a scene object already created or how to create a SceneBuilder object that could be used in place of the scene object.

SpaceCore186
  • 586
  • 1
  • 8
  • 22
Chika
  • 103
  • 1
  • 1
  • 4

5 Answers5

15

Once you created Scene and assigned it to the Stage you can use Stage.setWidth and Stage.setHeight to change both stage and scene sizes simultaneously.

SceneBuilder can't be applied to an already created object, it can only be used for the scene creation.

Sergey Grinev
  • 34,078
  • 10
  • 128
  • 141
  • Note that this answer is not the same as setting the _Scene_ width or height, because `Stage.setWidth()` and `Stage.setHeight` includes the window's decoration. See @user2229691's answer below if this matters to you. – MarcusOtter Mar 05 '21 at 01:19
3

It seems not possible to set the size of the Scene after it has been created.

Setting the size of the Stage means to set the size of the window, which includes the size of the decoration. So the Scene is smaller in size, unless the Stage is undecorated.

My solution is to compute the size of the decoration while initialization and add it to the size of the Stage when resizing:

private Stage stage;
private double decorationWidth;
private double decorationHeight;

public void start(Stage stage) throws Exception {
    this.stage = stage;

    final double initialSceneWidth = 720;
    final double initialSceneHeight = 640;
    final Parent root = createRoot();
    final Scene scene = new Scene(root, initialSceneWidth, initialSceneHeight);

    this.stage.setScene(scene);
    this.stage.show();

    this.decorationWidth = initialSceneWidth - scene.getWidth();
    this.decorationHeight = initialSceneHeight - scene.getHeight();
}

public void resizeScene(double width, double height) {
    this.stage.setWidth(width + this.decorationWidth);
    this.stage.setHeight(height + this.decorationHeight);
}
user2229691
  • 1,099
  • 12
  • 10
  • I think the API has changed a bit since this answer was written. `Scene.getX()` is now always equal to `initialSceneX`, so this answer will always give a decoration size of 0. To get this to work, I had to change the decoration calculation to `stage.getWidth() - initialWidth` and `stage.getHeight() - initialHeight`. But after that it worked flawlessly! This is exactly the smart solution I was looking for, thank you! – MarcusOtter Mar 05 '21 at 01:13
2

I just wanted to post another answer for those who might have had a similar problem as mine.

http://docs.oracle.com/javase/8/javafx/api/javafx/scene/Scene.html

There is no setWidth() or setHeight(), and the property is ReadOnly, but if you look at

Constructors

Scene(Parent root)
Creates a Scene for a specific root Node.

Scene(Parent root, double width, double height)
Creates a Scene for a specific root Node with a specific size.

Scene(Parent root, double width, double height, boolean depthBuffer)
Constructs a scene consisting of a root, with a dimension of width and height, and specifies whether a depth buffer is created for this scene.

Scene(Parent root, double width, double height, boolean depthBuffer, SceneAntialiasing antiAliasing)
Constructs a scene consisting of a root, with a dimension of width and height, specifies whether a depth buffer is created for this scene and specifies whether scene anti-aliasing is requested.

Scene(Parent root, double width, double height, Paint fill)
Creates a Scene for a specific root Node with a specific size and fill.

Scene(Parent root, Paint fill)
Creates a Scene for a specific root Node with a fill.

As you can see, this is where you can set the height and width if you need to.

For me, I am using SceneBuilder, just as you described you were doing, and needed the width and height of that. I am creating custom controls, so it was weird that it didn't do it automatically, so this is how to do it if you need to.

I could have used setWidth() / setHeight() from the Stage as well.

SpaceCore186
  • 586
  • 1
  • 8
  • 22
XaolingBao
  • 1,034
  • 1
  • 18
  • 34
0

I had an similar challenge when I wanted to switch between different size scenes in JavaFX.

I did my scene switching by changing the Parent resource of a Scene. The new resource would have larger dimensions than the previous resource so the entire Scene wasn't visible.

Like user2229691's answer stated - my issue turned out to be the Window not matching the Scene's dimensions.

Although I'm not able to comment about decorations - I was able to solve my issue by using: sceneName.getWindow().sizeToScene();

It works when downsizing and upsizing from my own testing.

Here's some example code so you can better understand what I did:

public void start(Stage stage) throws IOException {

    // Height of 300, width of 300
    Parent scene1 = FXMLLoader.load(getClass().getResource("scene1.fxml"));

    // Height of 400, width of 400
    Parent scene2 = FXMLLoader.load(getClass().getResource("scene2.fxml"));
    
    // Starting off in the smaller scene
    Scene mainScene = new Scene(scene1); // Scene & Window are 300x300
    stage.setScene(mainScene);
    stage.show();

    // Switching to the larger scene resource, that doesn't fit in the window
    mainScene.setRoot(scene2); // Scene is 400x400 but can only see 300x300
    
    // Resizing the window so the larger scene fits
    mainScene.getWindow().sizeToScene(); // Window is now 400x400 & everything is visible

}

I hope this helps someone.

Source:

https://docs.oracle.com/javase/8/javafx/api/javafx/stage/Window.html#sizeToScene--

0

Use AnchorPanes and set child nodes inside of said AnchorPanes to your liking then give the nodes of the of the AnchorPanes fx:ids. Go to your controller file and add the following to to where you want to resize the scene:

double elementIdNewWidth = 300;
double elementIdNewHeight = 300;
elementId.setPrefWidth(elementIdNewWidth);
elementId.setPrefHeight(elementIdNewHeight);
elementId.autosize();

If elementId is resizable, then the element will resize to 300 by 300 and the children inside of it will not change.

See:

https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Node.html#autosize--

https://docs.oracle.com/javafx/2/api/javafx/scene/control/Control.html#setPrefWidth(double)

https://docs.oracle.com/javafx/2/api/javafx/scene/control/Control.html#setPrefHeight(double)

Monomantle
  • 21
  • 4