2
votes

Using JavaFX, is there a way I can prevent a Node in the GUI tree from obtaining a reference to its parent node? Given this structure for example

AnchorPane > BorderPane > Pane

how can I be sure the last Pane won't be able to access it's parent BorderPane by calling .getParent()?

I need this because I'm loading "Pane" from untrusted code, and don't want it to mess with the main window components that contains it.

2
Document it. I hate it when that's an answer, but as answered, the implementation is going to allow you to run up the tree. You could also abstract the entire interface away, but I'd settle for documentation in this case. Trust your team! - Daniel B. Chapman
Unfortunately I can't just document it. As Pane extends javafx.scene.layout.Region, I could probably make a copy of that class with a different implementation of getParent(), though this still sounds more like a hack than a real solution... - Flavio
You're in a tough spot--as mentioned, the method is final and a hacked implementation won't fix anything. Is there a way you can start a second scene and sandbox it? You can run JavaFX inside a Swing GUI so theoretically you could sandbox it from Swing. At least this way you know the parent. As I recall that's a single-threaded approach so it might not be of interest. - Daniel B. Chapman
As far as I understand JavaFX language, "starting a new scene" means opening a new window. This could partially solve the problem since a scene is the root of its tree. However what I need is the ability to load external UI components into my GUI, and creating a new scene for each of them if out of the question... - Flavio
What I'm suggesting is you can embed an FX scene inside a JPanel. It is a pain (I was running SWT/Swing/FX in the same app for a while--don't ask--) weblogs.java.net/blog/ixmal/archive/2011/06/02/… You'll see that the root of this is actually a JPanel which means you can "swap them out" as needed. It is a bit of a pain to manage the threads but it isn't impossible. You can probably sandbox it this way, however, it isn't elegant. Also, it is a one way trip (Swing contains FX2) last time I checked there wasn't a reverse. - Daniel B. Chapman

2 Answers

0
votes

A solution is to insert an intermediate parent between your BorderPane and the untrusted Pane. This parent could blocks access to its own parent.

But, the methods getParent and parentProperty are final, there is no standard way to prevent a node from accessing to its parent.

Others options could be to get your own copy or the jre allowing to override the *parent* methods, or some hacky code based on reflection.

0
votes

You can use the Java Proxy API ( https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html ). This allow you to install a Security Manager surrounding one or more instances to monitor method calls (among other things).

Also you can use Thread.currentThread().getStackTrace() to obtain whom called any method and also you can add an additional node.

Another option option is to fork JavaFX source ( https://openjfx.io/ ) build it until it works (hard harder hardest! https://wiki.openjdk.java.net/display/OpenJFX/Building+OpenJFX ) and make some patches, so you get own implementation... in that case remember to use diff/patch for your changes so you can reapply your changes quickly over newer released versions of openjfx. Also try to automatize the build process, otherwise you will get stucked on older versions. Also maybe there are integration problems with some Java versions. Also you will probably need to build and deploy multiplattform dynamic libraries with your project :(

Or perhaps you can tweak JVM to replace some .class files without recompiling the whole JFX, but I'm not sure if this is possible.