One of the problems that cropped up while converting our Java3D PageFlow PDF viewer mode to JavaFX was the issue of how to replicate the z positioning of Java3D’s 3D scene with JavaFX’s 2D scene.
Scaling the size is an easy way to make things appear further away, but there was no obvious way to set a z-order to make one node appear in front of the other, mainly due to a distinct lack of a .setZ() or similar method.
The solution is that in JavaFX the Z-order of Nodes is not controlled by a z position property of the nodes, it is actually controlled by the order in which they appear in the scene graph.
Put another way, the order that you add your elements to the scene matters. If you add image 1 then add image 2, as image 2 was the last thing to be added it will therefore be the last thing to be drawn, so image 2 will appear in front of image 1.
To demonstrate, here’s a video of our JavaFX PageFlow mode:
As you can see, the page in the center is closest to us, and as pages get further from the center, they also move backward.
So to make all that appear in the correct order, the first thing to add to the scene is the 2 background colors. Next up are the pages. As the pages at the outer edges are furthest away they need to be added first. Rather than alternating between each side of the main page, as the pages on either side of the main page will never overlap I can actually do one side at a time. Then the main page gets added, and lastly the controls like the nav and zoom bars.
Here’s a quick visual demonstration:
In my code, this resulted in the creation of a reorder method whose job is specifically to pull out the pages in the scene graph, then put them back in the correct order.
Having this much control is definitely advantageous – it allows you to specifically optimize the sorting for your use case, but it’s also a little unclear. Perhaps it would be advantageous to have a simple setZ() method too. What do you think?
If you want to try out our new JavaFX PageFlow mode, you can download the free 14-day free trial of JPedal.
I have written several articles on converting our Java3D usage into JavaFX, check them out!
Are you a Developer working with PDF files?
Our developers guide contains a large number of technical posts to help you understand the PDF file Format.
Do you need to solve any of these problems?
|Display PDF documents in a Web app|
|Use PDF Forms in a web browser|
|Convert PDF Documents to an image|
|Work with PDF Documents in Java|
3 Replies to “How to set Z order of nodes in JavaFX”
You probably know that you could also sort the child nodes (rather than pulling them all out and adding them back in). See this technique use in the EarthCube example from JavaFX 2.0
Also, you may already have investigated Scene depthBuffer and Node depthTest, but you may find those helpful as well.
Thanks for commenting.
Using FXCollections.sort with a comparator is certainly a tidy way of ordering.
Looking back it’s clear that giving this much control is definitely a good thing. Whilst initially puzzling, it’s nice that allows you to define your own sort rather than having it sorted for you.
I have not investigated depthBuffer or depthTest (I probably should have!). I will do so when time permits.