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
- 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
- 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
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 parent Composite
in InverterPart#postConstruct(Composite)
- Create an instance of
javafx.scene.layout.BorderPane
- Create a
javafx.scene.Scene
instance that takes the created BorderPane
as root node and sets the background color to be the same as the background color of the parent Shell
- Set the created
javafx.scene.Scene
to the FXCanvas
// add FXCanvas for adding JavaFX controls to the UI
FXCanvas canvas = new FXCanvas(parent, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(canvas);
// create the root layout pane
BorderPane layout = new BorderPane();
// create a Scene instance
// set the layout container as root
// set the background fill to the background color of the shell
Scene scene = new Scene(layout, Color.rgb(
parent.getShell().getBackground().getRed(),
parent.getShell().getBackground().getGreen(),
parent.getShell().getBackground().getBlue()));
// set the Scene to the FXCanvas
canvas.setScene(scene); |
// add FXCanvas for adding JavaFX controls to the UI
FXCanvas canvas = new FXCanvas(parent, SWT.NONE);
GridDataFactory.fillDefaults().grab(true, true).span(3, 1).applyTo(canvas); // create the root layout pane
BorderPane layout = new BorderPane();
// create a Scene instance
// set the layout container as root
// set the background fill to the background color of the shell
Scene scene = new Scene(layout, Color.rgb(
parent.getShell().getBackground().getRed(),
parent.getShell().getBackground().getGreen(),
parent.getShell().getBackground().getBlue()));
// set the Scene to the FXCanvas
canvas.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 the BorderPane
javafx.scene.control.Label output = new javafx.scene.control.Label();
layout.setCenter(output); |
javafx.scene.control.Label output = new javafx.scene.control.Label();
layout.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 the RotateTransition
and the ScaleTransition
. This way both transitions are executed in parallel. - Add starting the animation in the
SelectionAdapter
and the KeyAdapter
that are executed for reverting a String.
RotateTransition rotateTransition = new RotateTransition(Duration.seconds(1), output);
rotateTransition.setByAngle(360);
ScaleTransition scaleTransition = new ScaleTransition(Duration.seconds(1), output);
scaleTransition.setFromX(1.0);
scaleTransition.setFromY(1.0);
scaleTransition.setToX(4.0);
scaleTransition.setToY(4.0);
ParallelTransition parallelTransition =
new ParallelTransition(rotateTransition, scaleTransition);
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
output.setText(StringInverter.invert(input.getText()));
parallelTransition.play();
}
}); |
RotateTransition rotateTransition = new RotateTransition(Duration.seconds(1), output);
rotateTransition.setByAngle(360);
ScaleTransition scaleTransition = new ScaleTransition(Duration.seconds(1), output);
scaleTransition.setFromX(1.0);
scaleTransition.setFromY(1.0);
scaleTransition.setToX(4.0);
scaleTransition.setToY(4.0);
ParallelTransition parallelTransition =
new ParallelTransition(rotateTransition, scaleTransition);
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
output.setText(StringInverter.invert(input.getText()));
parallelTransition.play();
}
});
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
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.