Inconsistent drawing/layouts of Dialogs & show()/showAndWait() differences
Martin Fox
martinfox656 at gmail.com
Mon Jul 7 14:50:05 UTC 2025
Cormac,
When you call Dialog.show everything happens in the order you expect. When you call Dialog.showAndWait the order of operations changes. For one, the Dialog code issues the DIALOG_SHOWN event *before* showing the window (it wants to send out that event before an internal call to Window.showAndWait blocks). For two, when Window.sizeToScene is called on a window that’s not yet visible it gets deferred. The end result is that with Dialog.showAndWait your onShown handler gets called before the window is sized to the scene but when you use Dialog.show your onShown handler is called after.
I don’t think any of this is documented. I've run into the deferred sizeToScene behavior before. I didn’t dig much but it looks like it was added over a decade ago in response to some bug reports. The timing of Dialog.setOnShown is also old behavior. There’s a comment in the Dialog.java about this:
> // this is slightly odd - we fire the SHOWN event before the show()
> // call, so that users get the event before the dialog blocks
So I can see what’s going on in case #2. Due to the re-ordering the sizeToScene logic is happening after the window’s minimum size is set. The docs don’t say what should happen if the scene’s desired size is less than the window’s minimum. What you’re getting is a scene that doesn’t fill the window. One work-around for case 2 is to call setOnShown on the dialog’s window instead of the dialog itself.
BTW, I think what you’re seeing in case #3 is correct and not a bug. You’re altering the size of the scene after the window has been sized and shown. I wouldn’t expect the window to automatically re-size to match the new scene dimensions. I think the expectation is that you would alter the scene’s dimensions in onShowing instead of onShown.
Martin
> On Jul 3, 2025, at 2:24 PM, Cormac Redmond <credmond at certak.com> wrote:
>
> Hi,
>
> I have noticed inconsistent and confusing size/layout behaviour with Dialogs when changing min width or height (after shown).
>
> The behaviour depends on whether changing min width/height on the Stage, or the DialogPane itself, and whether show() or showAndWait() is used.
>
> In summary:
> Set Stage mins + show()
> no bug
> Set Stage mins + showAndWait()
> improper layout: background applies only to label (i.e., size before re-size), button wrong position, re-sizing window fixes the problem
> 3 Set DialogPane mins + show()
> min sizes are ignored, button is visible, until it comes into focus, and then the button disappears, you can find it if you resize window close to the mins set
> 4 Set DialogPane mins + showAndWait()
> no bug
> It's happening in JFX23/24/25. Note, these may seem trivial/fixable, or you may ask "why would you do that?", but there are reasons I won't clutter the mail with.
>
> Anyway, it's best presented with a set of examples and code.
>
> Re points 1 and 2 above, exact same code, except red is showAndWait() and green is show():
>
> <image.png>
>
> Obviously, they should behave the same. Then slightly resize the red one:
>
> <image.png>
>
>
> Examples 3 and 4 above -- again, same code. Purple is show(), yellow is showAndWait().
>
> <image.png>
>
> After you close the yellow dialog:
>
> <image.png>
>
> They should be the same size from the outset.
>
>
>
> public class DialogBug extends Dialog<Boolean> {
>
> public DialogBug(final String s, boolean flip) {
> setTitle("Bug");
> setResizable(true);
>
> final DialogPane dp = getDialogPane();
> dp.setStyle(s);
> dp.getButtonTypes().add(ButtonType.CLOSE);
> dp.setContent(new Label("Content"));
>
> // Setting stage size causes the bug
> setOnShown(e -> {
>
> if (flip) {
> // Set stage sizes
> Stage st = (Stage) dp.getScene().getWindow();
> st.setMinHeight(260);
> st.setMinWidth(360);
> } else {
> // Set dialog sizes: note buttons disappear when you resize
> dp.setMinHeight(260);
> dp.setMinWidth(360);
> }
> });
> }
>
> public static class BugApp extends Application {
> @Override
> public void start(final Stage st) throws Exception {
>
> final boolean FLIP_ME = true; // make true for other bug
>
> if (FLIP_ME) {
> // Note: bug doesn't happen when using show() only. Stage is fully green on show.
> new DialogBug("-fx-background-color: green;", true).show(); // NO BUG
>
> // showAndWait presents the bug; background not fully drawn, button shifts on re-size
> new DialogBug("-fx-background-color: red;", true).showAndWait(); // BUG
> } else {
> // A different type of issue: two different sizes and button behaviour
> // Notice:
> // - same dialogs, different sizes
> // - how button in purple dialog shifts when yellow dialog pane is closed
> new DialogBug("-fx-background-color: purple;", false).show(); // BUG
>
> new DialogBug("-fx-background-color: yellow;", false).showAndWait(); // NO BUG
> }
> }
> }
> }
>
> Thoughts?
>
>
>
> Kind Regards,
> Cormac
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20250707/6583727b/attachment.htm>
More information about the openjfx-dev
mailing list