JavaFX and Jetbrains MPS

I am wondering why I cannot find the JavaFX libraries from MPS. Aren't they part of the JDK?

I could use them in IntelliJ IDEA without having to tweak any settings.

I cannot find neither how to pick the JDK to be used.

16 comments

An even weirder thing is happening: given I was not able to use JavaFX classes from inside MPS I wrote a little facade library. In particular I am using this class:

package com.voluntis.martian.javafx;

import javafx.application.Platform;
import javafx.concurrent.Worker;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import netscape.javascript.JSObject;

import java.awt.*;

public class JfxWrapper {

private WebView webView;
private WebEngine webEngine;

public JfxWrapper(Container container, String htmlCode, Object controller) {
JFXPanel jfxPanel = new JFXPanel(); // Scrollable JCompenent
Platform.runLater(() -> { // FX components need to be managed by JavaFX
webView = new WebView();
webEngine = webView.getEngine();

webEngine.loadContent(htmlCode);
webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
if (newValue == Worker.State.SUCCEEDED) {
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("controller", controller);
}
});
jfxPanel.setScene(new Scene(webView));
});
container.add(jfxPanel);
}
}


I then compile the JAR and use it inside MPS. It works... ONLY THE FIRST TIME I CREATE THE VIEW.
In practice I have an intention which creates a JFrame and inside the JFrame I use the JfxWrapper like this:

newJfxWrapper(panel,"<html><head></head><body><h1>HI!</h1></body></html>",newObject());

Now, if I start my intention I get this:

If I close the window and restart the intention the JavaFX Wrapper disappeared!

However if I restart MPS the first time I launch the intention it is there.
I am very puzzled by this




1

Thanks, voted and added a reference to this discussion.

BTW, using an external JAR it seems to work, I had just to consider how threads are used by JavaFX.

public class JfxWrapper {

private WebView webView;
private WebEngine webEngine;

public JfxWrapper(Container container, String htmlCode, Object controller) {
Platform.setImplicitExit(false);
System.out.println("GETTING STARTED");
JFXPanel jfxPanel = new JFXPanel(); // Scrollable JCompenent
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("CREATING WEBVIEW");
webView = new WebView();
webEngine = webView.getEngine();

webEngine.loadContent(htmlCode);
webEngine.getLoadWorker().stateProperty().addListener((observable, oldValue, newValue) -> {
System.out.println("UPDATE: "+newValue);
if (newValue == Worker.State.SUCCEEDED) {
JSObject window = (JSObject) webEngine.executeScript("window");
window.setMember("controller", controller);
System.out.println("CONTROLLER ADDED");
}
});
jfxPanel.setScene(new Scene(webView));
}
};
if(Platform.isFxApplicationThread()) {
System.out.println("IN FX APP THREAD");
runnable.run();
} else {
FutureTask<Object> task = new FutureTask<>((Callable<Object>) () -> {
runnable.run();
return null;
});
System.out.println("RUNNING THE TASK LATER");
Platform.runLater(task);
try {
task.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
container.add(jfxPanel);
}
}
1

Hi ,

I am also facing similar kind of situation.

When I use jfxrt jar (from jre->lib) as a stub, I am getting the error "glass.dll and many other dll's " are already loaded. So from this, I observe that the MPS is loading the java FX libraries also. But unable to directly use it :(

Regards,

Dinesh

 

0

Yes, that is the same for me: if copied the JAR under models and I tried to use it as a library but that does not work for the same error your reported (aside they are .so files because I am under Linux)

0

Hi ,

I don't know if we can unload the .dll or .so that are already loaded.

I haven't tried it.

Regards,

Dinesh

 

0

I also tried to explicitly add the JFX jar to the CLASSPATH in the mps.sh script but it did not help. Is it not clear to me why I can use let's say, java.util but not javafx.scene or any other javafx package

0

My observation is "For every class in java, there is a class inside MPS". There is no package called javafx.* available by default in the JDK provided by MPS. So only I tried using the jar as external library. But somewhere in MPS, they are loading all the DLL or .so files from JRE installed in our system or from jre shipped with MPS.

 

0

I do not think the MPS is shipped with a JRE/JDK: the mps.sh scripts try to locate the JDK to be used by looking at JAVA_HOME and other environment variables. So it is probably using the system JDK which in my case contains JavaFX. I suppose they do some sort of filtering for some reason.

0

I don't know whether they are filtering something.

But I think they are shipping JRE along with MPS..

You can see it in the MPS installation folder. Also in the .sh or .bat file, you can see that they are trying to find JDK_HOME,JAVA_HOME and then if nothing is there, they are using the the PROJECT_HOME\jre.

0

oh, I see. In my case anyway they are using the JAVA_HOME. Looking at the JDK solution I see they are getting the Jars from my system installation. However they are cherry-picking a few jars, instead of importing all of them

0

Oh. I understand that they are cherry-picking. I don't know which script loads the files from JDK and cherry picks few. But we can try to find out. :) 

0

Really this is a problem.. I faced this problem when I used JAVAFX with MPS. Since the MPS loads this DLL ( or .so), the sandbox solution will work as many times after you restart but the moment when you change something in the code and rebuild the same and then if you try to verify the sandbox solution whether your code change is getting reflected or not, it will throw the error that the DLL or .so is already loaded. So you need to restart the MPS to check/verify your code changes. I had this big headache and really affected the productivity. 

0

Ah. Hopefully this will be fixed atleast by 3.4 

0

 

@ Federico Tomassetti
 
Can you please explain this comment by you in the issue tracker. ? 
 
My workaround was to wrapping all JavaFX specific code in a library, build a JAR and import that JAR into MPS.
 
I also have a feature hanging somewhere waiting for some work around.
 
Regards,
 
Dinesh

 

0

In practice I created a JAR collecting classes that are using JavaFX, however no JavaFX classes are present in the API. If you see:

JfxWrapper(Container container, String htmlCode, Object controller)

Does not refer to any JavaFX class, however it uses JavaFX internally.
I just compiler this class into a JAR and created stubs in MPS for that JAR.
Now in MPS I can instantiate and use JfxWrapper without any problem because JFX is available at runtime, it was just not exposed at compile time. Trying to add it explicitly would cause that issues with native libraries being included twice, however by hiding JavaFX behind an API I do not need to refer to JavaFX at compile time inside MPS.
My case was rather simple because I just wanted to created a WebView, I do not know if the same technique could be applied if you need to work with several JavaFX classes.

0

Please sign in to leave a comment.