I am trying to integrate JavaFX inside of an SWT application using FXCanvas. For reference, I am following this oracle guide
Within my IDE this chunk of code displays an error
/* Create an FXCanvas */
final FXCanvas fxCanvas = new FXCanvas(shell, SWT.NONE) {
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
getScene().getWindow().sizeToScene();
int width = (int) getScene().getWidth();
int height = (int) getScene().getHeight();
return new Point(width, height);
}
};
Error:
(yes, I have imported the correct Point class: org.eclipse.swt.graphics.Point
):
'computeSize(int, int, boolean)' in 'Anonymous class derived from javafx.embed.swt.FXCanvas' clashes with 'computeSize(int, int, boolean)' in 'javafx.embed.swt.FXCanvas'; attempting to use incompatible return type
However, I don't think this is the root cause... Because when I try to build the project (maven) I get this error:
package javafx.embed.swt does not exist
. Which I believe is the true issue.
So after doing some research I have checked a few things, firstly, the jfxswt jar looks like it should be accessible:
and if I open the JAR, you can see FXCanvas is there:
I even tried adding the JAR manually as a library to my module, still doesn't work.
Here is my pom.xml, (i've intentionally anonymized certain info)
I will also mention that I have tried this in a fresh project without any maven dependencies, and just adding swt and such as libraries manually with the same error.
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
</parent>
<artifactId></artifactId>
<version>2.0.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name></name>
<description></description>
<dependencies>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-engine</artifactId>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-core</artifactId>
</dependency>
<dependency>
<groupId>pentaho-kettle</groupId>
<artifactId>kettle-ui-swt</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.swt</groupId>
<artifactId>org.eclipse.swt.gtk.linux.x86_64</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>jface</artifactId>
<version>3.3.0-I20070606-0010</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
</project>
Am I missing something, any ideas?
When JavaFX is embedded in SWT, a new preferred size is set for FXCanvas, enabling SWT to resize the embedded JFX content in the same manner as other SWT controls. JavaFX constructs content in terms of a hierarchical scene graph, placed inside a scene.
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.
When an SWT-JavaFX application is built, the JAR file must be packaged as a JavaFX application so the application on startup will look for the standalone JavaFX Runtime on the user's system. The SWT library (swt.jar) must be included as a resource (32-bit or 64-bit to match the target system).
On the one hand the OpenJFX libraries are available via Maven Central and can be added as extra classpath elements via Maven. But the javafx-swt module is not available via Maven Central as reported here.
You will need to add the jfxswt.jar
file to your classpath for compile and for execution.
This can be done by using the system scope as that jar file is part of your JDK under the jre/lib
directory.
<dependency>
<!-- GroupId/ArtifactId/Version doesn't matter unless it clashes. -->
<groupId>jfxswt</groupId>
<artifactId>jfxswt</artifactId>
<version>1.8</version>
<scope>system</scope>
<systemPath>${java.home}/lib/jfxswt.jar</systemPath>
</dependency>
This will instruct maven to add the jre/lib/jfxswt.jar
to the classpath. This could cause an issue if someone uses different JDK what has that jar in other places but for Java 8 you should be okay.
You have to add the jfxswt.jar
to your classpath when you execute your application.
In maven you can use the exec plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>twobuttons.TwoButtons</mainClass>
<additionalClasspathElements>
<!-- The run environment must configure the system jar. -->
<element>${java.home}/lib/jfxswt.jar</element>
</additionalClasspathElements>
</configuration>
</plugin>
Notes:
The system scope is deprecated in maven in favor of installing files to repositories. The solution above works fine at the moment.
The content of the jfxswt.jar
can be part of some SWT libraries unfortunately I am not familiar with SWT. If you can find that jar in a Maven repo than just include that instead of messing with the system scope.
The twobuttons.TwoButtons
class is from the tutorial you mentioned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With