Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embed a JavaFX application in a HTML webpage

I'd like to embed one ore more JavaFX applications on a webpage. How do you do that?

There are several bits and pieces on the Oracle website, but there's no complete example.

There's the Deployment in the Browser tutorial, the Packaging Basics tutorial, etc. There's mentioning of Ant tasks and what not.

So there were still a lot of questions after I read them. Like do I need Ant? Do I need to create an applet? etc

All I'd like to see is a minimal and complete "Hello World" example in order to see how it works. Even here on StackOverflow are only bits and pieces to answers of the same question, so that don't really help.

I had this question up yesterday, but deleted it and thought I'd try myself. Turned out that it is only easy when you know the pitfalls. So since this was already asked here I thought I'd share my minimal and complete example in the answer.

Using the JavaFX samples it took only a few minutes to create the code for this html page:

enter image description here

like image 699
Roland Avatar asked Jan 15 '15 06:01

Roland


1 Answers

Create a JavaFX application project, e. g. "FxInHtml".

Create your JavaFX application, e. g.:

package application;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;


public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            Group root = new Group();

            Label label = new Label( "Hello World!");
            root.getChildren().add( label);

            Scene scene = new Scene(root,200,200);

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

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

in FxInHtml/src/application

Now you can use the javafx packager tool to do the rest. You can find it in the bin folder of your JDK installation. Note that in Java 7 it's called javafxpackager and in Java 8 it's called javapackager. Let's assume we use Java 8 and your development environment compiled the class files into the bin folder.

Open a command shell and navigate to the project folder FxInHtml.

Create a package using

javapackager -createjar -outdir compiled -outfile myapp -appclass application.Main -srcdir bin -v

Now you have an executable myapp.jar file in the compiled folder.

Create the jnlp and html files using

javapackager -deploy -outdir deployed -outfile outfile -width 400 -height 400 -name AppName -appclass application.Main -v -srcdir compiled

The important thing to note is that "srcdir" is never any dir with java classes and it's different per javapackager directive. The output directory of the one javapackager call is the source dir of the other.

Now that you invoked the command, you got a new folder "deployed" which contains all the files you need: myapp.jar, outfile.html, outfile.jnlp.

If you open the outfile.html in a browser, you can already see the embedded JavaFX application. Most probably you'll have to change the security settings, e. g. allow "file:/" applications to be executed. But bear in mind that you remove "file:/" again after development, it is a security risk. Or you could sign the jar files which you'll have to do in the end anyway. You can use javapacker for the signing as well.

That's it for the minimal and complete example.


But let's look into the generated files. The generated outfile.html looks like this:

<html><head>
  <SCRIPT src="http://java.com/js/dtjava.js"></SCRIPT>
<script>
    function launchApplication(jnlpfile) {
        dtjava.launch(            {
                url : 'outfile.jnlp'
            },
            {
                javafx : '8.0+'
            },
            {}
        );
        return false;
    }
</script>

<script>
    function javafxEmbed() {
        dtjava.embed(
            {
                url : 'outfile.jnlp',
                placeholder : 'javafx-app-placeholder',
                width : 200,
                height : 200
            },
            {
                javafx : '8.0+'
            },
            {}
        );
    }
    <!-- Embed FX application into web page once page is loaded -->
    dtjava.addOnloadCallback(javafxEmbed);
</script>

</head><body>
<h2>Test page for <b>AppName</b></h2>
  <b>Webstart:</b> <a href='outfile.jnlp' onclick="return launchApplication('outfile.jnlp');">click to launch this app as webstart</a><br><hr><br>

  <!-- Applet will be inserted here -->
  <div id='javafx-app-placeholder'></div>
</body></html>

In order to embed various JavaFX applications, you need to modify/duplicate this part:

dtjava.embed(
    {
        url : 'outfile.jnlp',
        placeholder : 'javafx-app-placeholder',
        width : 200,
        height : 200
    },
    {
        javafx : '8.0+'
    },
    {}
);

and reference the application in your html using the placeholder using this div tag

<div id='javafx-app-placeholder'></div>

eg if you have an additional barchart.jnlp, you add it like this (I removed the webstart part since we want our app to be embedded):

    <html><head>
      <SCRIPT src="http://java.com/js/dtjava.js"></SCRIPT>
    <script>
        function javafxEmbed() {
            dtjava.embed(
                {
                    url : 'outfile.jnlp',
                    placeholder : 'javafx-app-placeholder',
                    width : 200,
                    height : 200
                },
                {
                    javafx : '8.0+'
                },
                {}
            );

            dtjava.embed(
                {
                    url : 'barchart.jnlp',
                    placeholder : 'barchart-placeholder',
                    width : 400,
                    height : 400
                },
                {
                    javafx : '8.0+'
                },
                {}
            );
        }
        <!-- Embed FX application into web page once page is loaded -->
        dtjava.addOnloadCallback(javafxEmbed);
    </script>

    </head><body>
      <h2>Test page for <b>AppName</b></h2>
      <!-- Applet will be inserted here -->
      <div id='javafx-app-placeholder'></div>

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tem
      <div id='barchart-placeholder'></div>
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequa ...
    </body></html>
like image 116
Roland Avatar answered Sep 23 '22 06:09

Roland