Threading and Node.lookup

Scott Palmer swpalmer at gmail.com
Tue Mar 19 18:34:58 PDT 2013


That's a different test.  What is ".text"?  Could it be an internal node generated by the Button Skin that doesn't exist until the Skin gets a chance to do it's thing?

Scott

On 2013-03-19, at 9:06 PM, John Smith <John_Smith at symantec.com> wrote:

>> I'm sure I used the lookup method to grab nodes from a scene graph that I made with Scene Builder *prior* to showing it.
> 
> It doesn't always work for me:
> 
> public class LookupTest extends Application {
>  public static void main(String[] args) { Application.launch(args); }
>  @Override public void start(Stage stage) {
>    Button button = new Button("xyzzy");
>    System.out.println("Before adding to scene: " + button.lookup(".text"));
> 
>    Scene scene = new Scene(button);
>    System.out.println("After adding to scene: " + button.lookup(".text"));
> 
>    stage.setScene(scene);
>    stage.show();
> 
>    System.out.println("After show: " + button.lookup(".text"));
>  }
> }
> 
> Outputs =>
> 
> Before adding to scene: null
> After adding to scene: null
> After show: LabeledText at 489863ce[styleClass=text]
> 
> -----Original Message-----
> From: Scott Palmer [mailto:swpalmer at gmail.com] 
> Sent: Tuesday, March 19, 2013 5:53 PM
> To: John Smith
> Cc: Philipp Dörfler; openjfx-dev at openjdk.java.net List
> Subject: Re: Threading and Node.lookup
> 
> On 2013-03-19, at 8:30 PM, John Smith <John_Smith at symantec.com> wrote:
>> "the node lookup function doesn't function (just returns null) until a rendering pass has been run on the scene"
> 
> 
> I don't think that is exactly right.  I'm sure I used the lookup method to grab nodes from a scene graph that I made with Scene Builder *prior* to showing it.
> 
> Yep. I just checked my code, this doesn't return nulls:
> 
> .
> Parent root = FXMLLoader.load(location); Scene scene = new Scene(root); Node top = scene.lookup("#top"); Node background = scene.lookup("#background"); .
> 
> The Scene clearly was just constructed and isn't showing or part of a Stage.
> The only difference is that this is called on the Platform thread. So something must be happening that needs to run on the Platform thread.
> 
> You are correct about the width/height stuff that requires a layout pass to have happened before you get reasonable values.
> 
> Scott
> 
> 
> 
>> +1 to Philipp's question.
>> 
>> It's always been the case that the node lookup function doesn't function (just returns null) until a rendering pass has been run on the scene.
>> 
>> With Philipp's sample at (https://gist.github.com/phdoerfler/5201162) , if you implemented it as an Application, placed the item to be looked up in a stage, and called lookup only *after* you called stage.show on your scene, then the lookup would work (without requiring Platform.runLater) - so some side effect of showing the scene on the stage allows nodes in the scene to be looked up.
>> 
>> It works the same way as trying to get the height and width of a node before it has been shown on stage - that also does not really work as you might expect because the css needs to be processed in the rendering pass to accurately determine the height and width.  I understand why height and width work the way they do, but I was never really sure why lookup doesn't just work immediately and the delayed behavior isn't documented anywhere.
>> 
>> Likely there is some hidden impl_ function you could use to trigger the rendering pass, after which the lookup would work.
>> 
>> - John
>> 
>> -----Original Message-----
>> From: openjfx-dev-bounces at openjdk.java.net 
>> [mailto:openjfx-dev-bounces at openjdk.java.net] On Behalf Of Kevin 
>> Rushforth
>> Sent: Tuesday, March 19, 2013 4:50 PM
>> To: Philipp Dörfler
>> Cc: openjfx-dev at openjdk.java.net List
>> Subject: Re: Threading and Node.lookup
>> 
>> One of the scene graph or FXML folks should be able to reply.
>> 
>> -- Kevin
>> 
>> 
>> Philipp Dörfler wrote:
>>> Ok, threading aside: Where's my mistake?
>>> 
>>> https://gist.github.com/phdoerfler/5201162
>>> 
>>> ~ philipp
>>> 
>>> Am 20.03.2013 um 00:30 schrieb Kevin Rushforth <kevin.rushforth at oracle.com>:
>>> 
>>> 
>>>>> As to my understanding, one only has to use Platform.runLater for accessing nodes already attached to a Scene.
>>>>> 
>>>> In general is is legal to call accessor and mutator methods on a Node not attached to a Scene from any thread. I don't specifically know whether lookup does anything that would add additional threading restrictions.
>>>> 
>>>> -- Kevin
>>>> 
>>>> 
>>>> Philipp Dörfler wrote:
>>>> 
>>>>> Hi,
>>>>> 
>>>>> does fooNode.lookup("#bar") have to be called using Platform.runLater if fooNode is not attached to any Scene?
>>>>> As to my understanding, one only has to use Platform.runLater for accessing nodes already attached to a Scene.
>>>>> 
>>>>> However, fooNode.lookup seems to fail (= return null) for nodes which are not contained directly in it, but in another node (in my case: a ScrollPane), which is then contained in fooNode. The scene graph was provided by FXMLLoader.load(...).
>>>>> 
>>>>> Placing those lookups in Platform.runLater suddenly causes them to work.
>>>>> 
>>>>> This feels like an arcane bug to me, but I might be missing some core concepts.
>>>>> So - did I miss something or is this a bug?
>>>>> 
>>>>> Cheers,
>>>>> Philipp
>>>>> 
>>> 
>>> 
> 



More information about the openjfx-dev mailing list