Threading and Node.lookup
Scott Palmer
swpalmer at gmail.com
Tue Mar 19 20:47:08 PDT 2013
Yes, good point. In that case I could delay the connection to the Scene object and instead do the lookup via the root node. But still in this case, has a rendering pass ("pulse") happened yet on such a Scene? Since Scene objects must be constructed and modified on the FX app thread I guess it makes sense that they would do an initial layout pass on the root node? So perhaps John is correct. It's late and I don't have time to construct a test case now.
Scott
On 2013-03-19, at 10:35 PM, Kevin Rushforth <kevin.rushforth at oracle.com> wrote:
> > Node background = scene.lookup("#background");
>
> Note that this particular call references a scene, so must be done on the FX application thread. You should not touch the scene or a node that is connected to a scene on a background thread.
>
> -- Kevin
>
>
>
> Scott Palmer wrote:
>>
>> 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