Question

I can't seem to find anything on this - other than it can't be embedded in a web view.

I currently have an image viewing product which is accessed via an applet and controlled via JavaScript from an HTML page.

I am investigating a client application using JavaFX and it would likely need to access that applet. I attempted to embed it into the WebView and that didn't work. Searching on this site stated that webview doesn't support plug in technology. This is to build an applet with Java FX - but rather to invoke and interact with an existing product.

Therefore I am left wondering if there is another way - using JavaFX 8?

Thanks!

Was it helpful?

Solution

A quick trial with a really simple sample applet, demonstrates that it is possible to embed Swing applets into JavaFX applications (with Java 8).

Sample

hello

Here is the HelloWorld applet from the Oracle getting started with applets documentation:

import javax.swing.*;

public class HelloWorldApplet extends JApplet {
    public void init() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    JLabel lbl = new JLabel("Hello World");
                    add(lbl);
                }
            });
        } catch (Exception e) {
            System.err.println("createGUI didn't complete successfully");
        }
    }
}

And here is a JavaFX application which embeds it:

import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import javax.swing.JApplet;
import javax.swing.SwingUtilities;
import java.awt.Dimension;

import java.util.concurrent.*;

public class JavaFXSwingAppletHolderApplication extends Application {
    private JApplet applet = new HelloWorldApplet();
    private Dimension appletSize;

    @Override public void init() throws ExecutionException, InterruptedException {
        applet.init();

        FutureTask<Dimension> sizingTask = new FutureTask<>(() ->
            applet.getRootPane().getPreferredSize()
        );
        SwingUtilities.invokeLater(sizingTask);
        appletSize = sizingTask.get();
    }

    @Override public void start(Stage stage) {
        final SwingNode swingNode = new SwingNode();
        SwingUtilities.invokeLater(() ->
            swingNode.setContent(applet.getRootPane())
        );

        stage.setScene(
            new Scene(
                new Group(swingNode),
                appletSize.getWidth(), appletSize.getHeight(),
                Color.BLACK
            )
        );
        stage.show();
    }

    @Override public void stop() {
        applet.stop();
        applet.destroy();
    }

    public static void main(String[] args) {
         launch(args);
     }
}

Notes

I'm not sure if the sizingTask is the above code is strictly necessary, I just stuck it in there just in case as I know little about Swing layout, so thought it best to be explicit.

This sample only embeds a basic applet, your applet will be more complex so you will need to validate a similar solution for your particular applet to ensure it works for you.

Recommendation

Most existing applets are quite small - it is probably a better idea to reimplement an applet as a pure JavaFX component implementation rather than try to embed the applet in a JavaFX application.

Also note that the applet API is deprecated as part of Java 9, by JEP 289: Deprecated the Applet API.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top