Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use FXCanvas with SWT Java 8

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:

enter image description here

and if I open the JAR, you can see FXCanvas is there: enter image description here

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?

like image 324
rhowell Avatar asked Dec 02 '20 21:12

rhowell


People also ask

How does JavaFX work with SWT and fxcanvas?

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.

What is JavaFX interoperability with SWT?

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.

What is the SWT-JavaFX JAR file?

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).

Is JavaFX-SWT available via Maven Central?

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.


1 Answers

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.

like image 100
Gebezs Avatar answered Oct 18 '22 14:10

Gebezs