I have wanted to play with using Java FX for some of my programs, but it hasn’t been easy to work with in either Eclipse or Linux. This time though, with the help of some other articles across the Internet, I was able to get a small sample Java FX program running from Eclipse. Here’s my notes from my explore:
Installing
I added the site: http://downloads.efxclipse.org/p2-repos/releases/latest/. You can do that with Window > Preferences. Then, the sites are located under Install/Update > Available Software.
Afterward, I used the install dialog to install the two features suggested by the install instructions:
- e(fx)clipse – Composite – FX Tooling (under e(fx)clipse tooling)
- Jemmy FX to Junit Test OSGi-Apps (under e(fx)clipse installable)
I did get a security warning:
At the end, it prompted for rebooting:
After Eclipse restarted, I had a new option under File > New Project … for JavaFX:
Adding the Required Library
The first thing I noticed in my new project was the red lines indicating errors:
Several of the posts mentioned including the jfxrt.jar. They mentioned that it was located at “.\Program Files\Oracle\JavaFX 2.1 Runtime\lib” in Windows. I found it on my Linux machine at /usr/lib/jvm/java-7-oracle/jre/lib/jfxrt.jar
So, I added that Jar to the build path:
In the build path screen, I selected the jar file:
After that, the errors disappeared.
Seeing it Work
Next, I wanted to see it work. So, I followed the first tutorial on the e(fx)clipse site, and added this code to the start() method:
BorderPane p = new BorderPane(); Text t = new Text("Hello FX"); t.setFont(Font.font("Arial", 60)); t.setEffect(new DropShadow(2,3,3,Color.RED)); p.setCenter(t); primaryStage.setScene(new Scene(p)); primaryStage.show();
Then, I could simply click the run button, and it displayed the window:
Using the Scene Builder
Next, I had installed the Scene Builder so I wanted to try to use that with my Eclipse code. To get that working, I first set the path to the program in the settings. Window > Perferences and under JavaFX. For me, the path was /opt/JavaFXSceneBuilder1.1/JavaFXSceneBuilder1.1
Then, I added the JXML file by right clicking on package where I wanted to insert it. I chose New > Other …
I chose JavaFX > New FXML Document
I chose a name, and I checked the dynamic root option. I am not sure if the dynamic root was necessary.
This gave me a basically empty FXML document. I could open it with Scene Builder by right clicking on the document in the Package Explorer.
In the scene builder, I added a new label just so that I would have something to see.
After finishing in Scene Builder, I saved, closed it, and went back to Eclipse. Eclipse then displayed the new generated XML.
Now, it was time to change my code in my application. I changed the start() method to this:
Parent root = null; try { root = FXMLLoader.load(getClass().getResource("/net/digitaleagle/javafxtest/SceneTest.fxml")); } catch (IOException e) { e.printStackTrace(); System.exit(1); } primaryStage.setScene(new Scene(root)); primaryStage.show();
And, it worked when I ran it!
Note that if you type the path to the FXML document wrong, you will get a “Location is required” exception.
Exception in Application start method Exception in thread "main" java.lang.RuntimeException: Exception in Application start method at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403) at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47) at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115) at java.lang.Thread.run(Thread.java:722) Caused by: java.lang.NullPointerException: Location is required. at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2737) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2721) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2707) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2694) at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2683) at net.digitaleagle.javafxtest.JavaFXTest.start(JavaFXTest.java:22) at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319) at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:206) at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:173) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76) at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method) at com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:82) ... 1 more
If you get this exception, make sure that you have spelled everything correctly. Also, make sure that you start with a slash (/). That was my mistake the first time. If that still doesn’t fix it, make sure that the FXML document is in your compiled class folder and not just the source folder. Eclipse was copying it there for me, so I didn’t have to worry about that.
Update: e(fx)lipse and library
Tom pointed out that I should not have to add the jfxrt.jar to the classpath. I kind of suspected that, but it was the easiest solution. For me, it doesn’t show any jar files under the JavaFX SDK.
Under Help > Installation Details, I confirmed that I am using the Java 1.7 JVM:
Resources
- Stack Overflow: Is there an Eclipse plugin for JavaFX 2.0?
- Tomsondev Blog: e(fx)clipse 0.0.7 released
- e(fx)clipse: Download & Install
- e(fx)clipse: From creation to deployment
- JavaFX for Swing Developers: 2 Integrating JavaFX into Swing Applications
- DZone: Add a JavaFX Component Built with Scene Builder and FXML to a NetBeans RCP Application
You should not need to add jfxrt.jar if you created your project with the wizard.
There’s a classpath-library set on your project (JavaFX SDK) which should locate the javafxrt.jar in your JDK/JRE install if you use at least Java7u7. If this does not work it is a bug on Linux and needs to be fixed.
Tom, thanks for pointing that out. I added a screenshot at the end — I am thinking the jfxrt.jar should be listed under the JavaFX SDK.
Should I file a bug report? Can you point me in the right direction how I can help?
I have get “Caused by: java.lang.NullPointerException: Location is required.”..I have double check my spellings and the the location of the .fxml is also correct i guess,i have hardcoded the location (compiled class folder)..but it still not working