Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generating image at server side using Java FX

Currently I'm working on Jax Rs application and I want to output Base64 encoded image to the client. The client is a mobile device.

The mobile device will call this service with some parameters and the server has to draw a bar chart and send it back to the device as a base64 encoded image string.

Since java Fx having the required chart libraries, I did a sample using following tutorial. "snapshot" function also worked correctly as expected (to create a image of the screen).

http://docs.oracle.com/javafx/2/charts/bar-chart.htm#CIHJFHDE

Now I want to do this without extending Application class because I need to this within the Jax Rs application. So that I can just use api to create a BuffredImage and then use that for create Base64 string.

I found a way to do this using JFreeChart. But I prefer if I can do this using Java FX. I do not having any previous experience with Java Fx

Please advice

like image 561
Chanaka Perera Avatar asked Dec 04 '13 08:12

Chanaka Perera


People also ask

How do I add an image to JavaFX GUI?

Create a FileInputStream representing the image you want to load. Instantiate the Image class bypassing the input stream object created above, as a parameter to its constructor. Instantiate the ImageView class. Set the image to it by passing above the image object as a parameter to the setImage() method.

Is JavaFX the same as Java?

JavaFX is an open-source web platform that enables developers to create modern user interfaces for desktop, mobile, and browser applications. Java Swing is a GUI toolkit for Java, originally designed by Sun Microsystems. It is one of the most popular toolkits in the world.

What does JavaFX stand for?

JavaFX stands for special effects in the Java language. Internet applications are made richer with different plugins with the help of JavaFX. This is an alternative to the ways for building a website or any other applications. We can say JavaFX is a declarative and statically typed scripting language.


1 Answers

Server based JavaFX runtime Initialization

To run JavaFX on a server you need to either:

  1. Launch a JavaFX Application OR
  2. Use a JFXPanel.

Those are the only ways to get the JavaFX runtime system initialized in JavaFX 2 so that you can use it.

Using a JFXPanel is probably slightly less efficient processing wise than using a JavaFX Application.

There is further discussion on initialization of the JavaFX system in the StackOverflow question: JavaFX 2.1: Toolkit not initialized.

JavaFX is a single threaded system

You can create most JavaFX components in any thread. However to render components in a scene, you must perform the work on the JavaFX Application thread. This means that if you have a multi-threaded server process, which most servers are, and you want to generate multiple charts, you will need to single thread the chart rendering requests using concurrency constraints.

  1. When you get an incoming request for a chart, issue a Platform.runLater command. All code in the runLater block will be placed in a queue that will eventually run on the JavaFX application thread.
  2. In the runLater block create a scene for your chart and snapshot it to an image. The callback version of snapshot might be the most appropriate one to use here as it likely doesn't tie up the JavaFX Application Thread as much, though it is likely tricker to use.
  3. Convert the JavaFX image to a AWT image using SwingFXUtils.fromFXImage.
  4. To get your image result back in your server handler thread, use the FutureTask technique outlined by sarcan in: Return result from javafx platform runlater.

Your server handler thread can then use ImageIO to convert the AWT image to an output stream in a format like png. You can take the result stream and Base64 encode it and have the server return the base 64 encoded stream in response to the original image request call.

Ensure graceful shutdown

You will want to invoke Platform.setImplicitExit(false) when your server starts up and register a shutdown hook or a ServletContextListener that monitors when the servlet is being destroyed, so that you also invoke Platform.exit() to shutdown the JavaFX system. If you don't do this, likely your server won't be able to shut down cleanly because the JavaFX application thread will continue running awaiting work to do.

JavaFX 2.2 is not really certified to run on a headless server

Swing applications can run in headless mode using a system property java.awt.headless. I am not aware of a similar property for JavaFX, though there may one and, if there were, you might find out what it was by asking the openjfx-dev mailing list.

JavaFX is primarily designed as a client graphics toolkit. While you might get it to work and run satisfactorily for your application on a server, to do so, you may need to ensure that the server is not setup as a headless server and that it has an appropriate graphic accelerator card to provide reasonable performance under load.

You can file a request for official support of a headless mode in the JavaFX issue tracker.

like image 55
jewelsea Avatar answered Sep 16 '22 19:09

jewelsea