JDK-8130675 : Document that setting scene on stage changes stage size unless explicitly set
  • Type: Bug
  • Component: javafx
  • Sub-Component: scenegraph
  • Affected Version: 8u45,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2015-07-07
  • Updated: 2020-01-31
  • Resolved: 2016-08-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
8u152Fixed 9Fixed
Related Reports
Blocks :  
A user can change the stage's size, e. g. using the mouse. As a result, the shown scene is resized. This means, a scene adopts to the user's wishes.

When replacing the scene in that stage, the stage resizes to the size the new scene requests. This means, the scene ignores the user's previous wishes.

This behaviour is inconsistent. Either it is the user who gives the size (so changing the scene does not resize the stage) or it is the scene who gives the size (so resizing the window by user is impossible). But it makes no sense to override the user's wishes in case there is no real technical force to do so.

This might be by design, but this design is inconsistent and counterintuitive. So I'd say this is a bug. What users want is certainly to keep the user-provides size EVER until the user either demands to get the scene's default size, or he does another manual size change. But literally NOBODY wants wrigging windows!
Approved to backport to 8udev for 8u122. If the patch applies cleanly (after adjusting the path names), then no need to publish a webrev.

Request for backport to 8u-dev.

Changeset: 4c8db4731758 Author: ckyang Date: 2016-08-16 14:12 -0700 URL: http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/4c8db4731758


Thanks for the feedback. Here is the revised webrev.01: http://cr.openjdk.java.net/~ckyang/JDK-8130675/webrev.01

Three comments (the first isn't something you changed, but ought to be fixed anyway in the methods that you are changing). 1) The methods you changed refer to Stage rather than Window. Since these are methods of the Window class we should replace {@code Stage} with {@code Window}. 2) The following is somewhat ambiguous which width (or height) you are referring to when you say "this width": * This width will take the width from the scene ... I recommend a slight change to: * This window will take its width from the scene ... 3. Similarly, the following * If the width or height of this {@code Stage} have never been set by the * application, setting a scene to this {@code Stage} will take the width or * height from that scene. might be better worded as: * If the width or height of this {@code Window} have never been set by the * application, setting the scene will cause this {@code Window} to take its width or * height from that scene.

Please review this proposed doc fix: http://cr.openjdk.java.net/~ckyang/JDK-8130675/webrev.00/

Kevin, thank you for the workaround. It indeed solves the problem! :-) On the other hand I need to say that I do not see what the benefit of this particular design choice should be. An end user gives an explicit size to the stage by resizing the window, and that size is discarted in case the Scene is replaced, unless that above workaround is applied. From the end user's perspective I need to say thay nobody in my team could see any good reason where an end user would either expect or appreciate that... we see this as counter-intuitive, violating the design principle of least astonishment. So can you please elaborate what the idea you had behind this design choice, i. e. what benefit it brings to end users / programmers? I mean, following CoC apparently virtually everybody would say that our workaround should be enabled by default.

This is by design, but the documentation is not clear. If width or height have not ever been set by the application, stage.setScene(scene) will take the width or height from the scene. The logic of setScene is as follows: if (stage.width has never been explicitly set) { stage width = scene width + window_decoration.width } if (stage.height has never been explicitly set) { stage.height = scene.height + window_decoration.height } If you add the following after stage.show() then it will do what you expect: Platform.runLater(() -> { stage.setWidth(stage.getWidth()); stage.setHeight(stage.getHeight()); }); This only needs to be done once, when the stage is first shown.

Example: package foo; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.stage.Stage; public class StageTest extends Application { public static void main(final String[] args) { Application.launch(args); } @Override public void start(final Stage stage) { final Button button1 = new Button("Show Scene 2"); final Scene scene1 = new Scene(button1); final Button button2 = new Button("Show Scene 1"); final Scene scene2 = new Scene(button2); button1.setOnAction(e -> stage.setScene(scene2)); button2.setOnAction(e -> stage.setScene(scene1)); stage.setScene(scene1); stage.show(); } }