Node.lookupAll behaves differently before Scene is shown

John Hendrikx john.hendrikx at gmail.com
Sat Dec 24 08:34:15 UTC 2022


Hi,

In this case, this is because SplitPane doesn't actually add its split 
items as children -- only its Skin does this.  Skins are AFAIK installed 
after a CSS pass.

In the split pane case, I guess a Skin could choose to completely leave 
out a child if its splitter completely hides it (ie, dragged all the way 
to the left or right if allowed).

This may be another case where it may make sense to have both a document 
graph (logical graph) and a scene graph as Michael Strauss mentioned 
here: https://mail.openjdk.org/pipermail/openjfx-dev/2022-June/034417.html

I doubt this is documented anywhere at all, it's one of those things 
that doesn't work quite right in JavaFX before a Scene is displayed.

--John

On 23/12/2022 23:49, Scott Palmer wrote:
> I just want to make sure this is not expected behaviour. I don’t think 
> so, the documentation for lookupAll doesn’t mention anything related, 
> but maybe I missed something somewhere else.
>
> I was just coding something to query the Scene for all SplitPanes and 
> save/restore the divider positions for when my application is exiting 
> and launching and came across this issue.
> My UI is fully constructed (at least in terms of all the SplitPanes in 
> the scene graph) before it is shown.
>
> This  code:
>
> window.getScene().getRoot().lookupAll(".split-pane")
>
> returns a different number of Nodes if I call it before showing the 
> window versus after showing the window.  Specifically, if I call it 
> before showing the window it appears to only return the first 
> SplitPane found in the scene graph, but calling it in an event handler 
> for the window shown event I get all three.
>
> This can be demonstrated with the following program:
>
>
> import javafx.application.Application;
> import javafx.scene.Scene;
> import javafx.scene.control.SplitPane;
> import javafx.scene.control.TextArea;
> import javafx.scene.layout.BorderPane;
> import javafx.stage.Stage;
> import javafx.stage.Window;
>
> public class LookupAll extends Application {
>     Window mainWindow;
>     public static void main(String[] args) {
>         launch(args);
>     }
>     @Override
>     public void start(Stage primaryStage) throws Exception {
>         var bp = new BorderPane(new SplitPane(new TextArea(),new 
> SplitPane(new TextArea(),new SplitPane(new TextArea()))));
>         var scene = new Scene(bp);
> primaryStage.setScene(scene);
>         mainWindow = primaryStage;
>         System.out.println("Before showing:");
>         countSplitPanes();
>         primaryStage.setOnShown(we -> {
> System.out.println("After showing:");
>             countSplitPanes();
>         });
>         primaryStage.show();
>     }
>     private void countSplitPanes() {
>         var splitPanes = 
> mainWindow.getScene().getRoot().lookupAll(".split-pane");
>         System.out.printf("Found %d SpitPanes: 
> %s\n",splitPanes.size(), splitPanes);
>     }
> }
>
>
>
> Before showing:
> Found 1 SpitPanes: [SplitPane at 16bca2d9[styleClass=split-pane]]
> After showing:
> Found 3 SpitPanes: [SplitPane at 16bca2d9[styleClass=split-pane], 
> SplitPane at 7078ef3c[styleClass=split-pane], 
> SplitPane at 56a29626[styleClass=split-pane]]
>
>
> Regards,
>
> Scott
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20221224/8813013c/attachment-0001.htm>


More information about the openjfx-dev mailing list