As explained in JavaFX Interoperability with SWT it is possible to embed JavaFX controls in a SWT UI. This is useful for example if you want to softly migrate big applications from SWT to JavaFX or if you need to add animations or special JavaFX controls without completely migrating your application.
The following recipe will show how to integrate JavaFX with an Eclipse 4 application.
Cookware
- JDK 8
- http://www.oracle.com/technetwork/java/javase/downloads/index.html
- Simply run the executable and follow the installation instructions
- e(fx)clipse IDE 1.2.0
- JavaFX tooling and runtime for Eclipse and OSGi
- http://efxclipse.bestsolution.at/install.html#all-in-one
- Ensure the IDE is started with Java 8 if you have multiple Java versions installed
- Edit the file eclipse.ini which is located in the e(fx)clipse installation directory
- Add the following lines (typically before -showsplash)
-vm C:/Program Files/Java/jre8/bin/javaw.exe
See https://wiki.eclipse.org/Eclipse.ini#Specifying_the_JVM for further information.
- After starting the IDE and choosing a workspace, update the IDE to ensure the latest service release is installed. This is necessary to get the latest bugfixes and security patches.
- Main Menu → Help → Check for Updates
Ingredients
This recipe uses the Eclipse RCP Cookbook – Basic Recipe . To get started fast with this recipe, we have prepared the basic recipe for you on GitHub .
If you want to use the prepared basic recipe to follow the migration from SWT to JavaFX, import the project by cloning the Git repository:
- File → Import → Git → Projects from Git
- Click Next
- Select Clone URI
- Enter URI https://github.com/fipro78/e4-cookbook-basic-recipe.git
- Click Next
- Select the master branch
- Click Next
- Choose a directory where you want to store the checked out sources
- Click Next
- Select Import existing projects
- Click Next
- Click Finish
Preparation
Step 1: Update the Target Platform
- Open the target definition de.codecentric.eclipse.tutorial.target.target in the project de.codecentric.eclipse.tutorial.target
- Add a new Software Site by clicking Add… in the Locations section
- Select Software Site
- Software Site for the e(fx)clipse 1.2.0 release build
http://download.eclipse.org/efxclipse/runtime-released/1.2.0/site - Expand FX Target and check RCP e4 Target Platform Feature
- Click Finish
- Add a new Software Site by clicking Add… in the Locations section
- Select Software Site
- Software Site for Orbit
http://download.eclipse.org/tools/orbit/downloads/drops/R20150124073747/repository/ - Expand Orbit Bundles By Name: org.apache.* and check Apache Jakarta log4j Plug-in
(this is a necessary dependency for the RCP e4 Target Platform Feature) - Click Finish
- Activate the target platform by clicking Set as Target Platform in the upper right corner of the Target Definition Editor
Note:
With the upcoming e(fx)clipse 2.0 release it is not necessary to add the Apache Jakarta log4j Plug-in to the Target Definition! If you want to play with the current development state of e(fx)clipse 2.0, use the e(fx)clipse Nightly Build Software Site http://download.eclipse.org/efxclipse/runtime-nightly/site. In that case you also need to update the Target Definition to use Eclipse Mars via the Milestone Software Site http://download.eclipse.org/eclipse/updates/4.5milestones.
Step 2: Update the Plug-in project
- Update the bundle dependencies
- Open the file MANIFEST.MF in the project de.codecentric.eclipse.tutorial.inverter
- Switch to the Dependencies tab
- Add the following packages to the Imported Packages
- javafx.*
Note: With the upcoming e(fx)clipse 2.0 release it is not necessary to add the javafx.* packages to the Imported Packages!
- Open the
InverterPart
in the project de.codecentric.eclipse.tutorial.inverter- Add a
javafx.embed.swt.FXCanvas
to the parentComposite
inInverterPart#postConstruct(Composite)
- Create an instance of
javafx.scene.layout.BorderPane
- Create a
javafx.scene.Scene
instance that takes the createdBorderPane
as root node and sets the background color to be the same as the background color of the parentShell
- Set the created
javafx.scene.Scene
to theFXCanvas
- Add a
1// add FXCanvas for adding JavaFX controls to the UI 2FXCanvas canvas = new FXCanvas(parent, SWT.NONE); 3GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(canvas); 4 5// create the root layout pane 6BorderPane layout = new BorderPane(); 7 8// create a Scene instance 9// set the layout container as root 10// set the background fill to the background color of the shell 11Scene scene = new Scene(layout, Color.rgb( 12 parent.getShell().getBackground().getRed(), 13 parent.getShell().getBackground().getGreen(), 14 parent.getShell().getBackground().getBlue())); 15 16// set the Scene to the FXCanvas 17canvas.setScene(scene);
Now JavaFX controls can be added to the scene graph via the BorderPane
instance.
- Remove the output control of type
org.eclipse.swt.widgets.Text
- Create an output control of type
javafx.scene.control.Label
- Add the created
javafx.scene.control.Label
to the center of theBorderPane
1javafx.scene.control.Label output = new javafx.scene.control.Label(); 2layout.setCenter(output);
Add some animations to see some more JavaFX features.
- Create a
javafx.animation.RotateTransition
that rotates the output label. - Create a
javafx.animation.ScaleTransition
that scales the output label. - Create a
javafx.animation.ParallelTransition
that combines theRotateTransition
and theScaleTransition
. This way both transitions are executed in parallel. - Add starting the animation in the
SelectionAdapter
and theKeyAdapter
that are executed for reverting a String.
1RotateTransition rotateTransition = new RotateTransition(Duration.seconds(1), output);
2rotateTransition.setByAngle(360);
3
4ScaleTransition scaleTransition = new ScaleTransition(Duration.seconds(1), output);
5scaleTransition.setFromX(1.0);
6scaleTransition.setFromY(1.0);
7scaleTransition.setToX(4.0);
8scaleTransition.setToY(4.0);
9
10ParallelTransition parallelTransition =
11 new ParallelTransition(rotateTransition, scaleTransition);
12
13button.addSelectionListener(new SelectionAdapter() {
14 @Override
15 public void widgetSelected(SelectionEvent e) {
16 output.setText(StringInverter.invert(input.getText()));
17 parallelTransition.play();
18 }
19});
Step 3: Update the Feature project
- Open the file feature.xml in the project de.codecentric.eclipse.tutorial.feature
- Switch to the Plug-ins tab
- Add the following plug-ins to the list of Plug-ins and Fragments
- org.apache.commons.lang
- org.apache.log4j
This step is necessary because these plug-ins are missing in the org.eclipse.fx.target.rcp4.feature in e(fx)clipse 1.2.0.
Note: With the upcoming e(fx)clipse 2.0 release this step is not necessary!
Step 4: Update the Product Configuration
- Open the file de.codecentric.eclipse.tutorial.app.product in the project de.codecentric.eclipse.tutorial.product
- Switch to the Dependencies tab
- Add org.eclipse.fx.target.rcp4.feature
- Switch to the Launching tab
- Add -Dosgi.framework.extensions=org.eclipse.fx.osgi to the VM Arguments
Step 5: Taste
- Start the application from within the IDE
- Open the Product Configuration in the de.codecentric.eclipse.tutorial.product project
- Select the Overview tab
- Click Launch an Eclipse Application in the Testing section
The started application should look similar to the following screenshot.
If you want to create a deliverable via the PDE export, you need to configure the jfxswt.jar file as an external compile time library. Otherwise you will see compile errors on export since that library is not part of any classpath because of the dependency to SWT.
In a productive environment you should not rely on such a workaround! The best practice here is to setup a headless build using Maven Tycho for example.
- Prepare the build classpath for PDE export
- Create the directory lib in the project de.codecentric.eclipse.tutorial.inverter
- Copy the file jfxswt.jar from JAVA_HOME/lib on your machine to this directory
- Open the file build.properties in the project de.codecentric.eclipse.tutorial.inverter
- Expand the Extra Classpath Entries section at the bottom of the Build Properties Editor
- Add the entry lib/jfxswt.jar via Add JARs…
- Export the application and start the deliverable
- Open the Product Configuration in the de.codecentric.eclipse.tutorial.product project
- Select the Overview tab
- Click Eclipse Product export wizard in the Exporting section
- Select a directory to export to in the Destination section of the export wizard
- Leave the other options unchanged
- Click Finish
- After the export is done, open the directory the application was exported to and start the application via the native executable
- Note that this might not work correctly on a Mac because of some issues with the PDE export and Mac. In that case uncheck The product includes native launcher artifacts on the Overview tab of the Product Configuration and start the application by executing the following command on the command line
java -jar plugins/org.eclipse.equinox.launcher_$VERSION.jar
- Note that this might not work correctly on a Mac because of some issues with the PDE export and Mac. In that case uncheck The product includes native launcher artifacts on the Overview tab of the Product Configuration and start the application by executing the following command on the command line
The complete source code of the example can be found on GitHub .
Feel free to contact me via email or comments section if you have further questions or thoughts about this recipe.
More articles
fromDirk Fauth
Your job at codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog author
Dirk Fauth
Do you still have questions? Just send me a message.
Do you still have questions? Just send me a message.