Interoperability between Graphics2D and GraphicsContext

merv picture merv · Jun 12, 2013 · Viewed 7.6k times · Source

I am working with a group that is looking to target a graphics renderer in Java. I am trying to figure out whether targeting java.awt.Graphics2D will be forward compatible. Namely, can other libraries like JavaFX display renders from a Graphics2D instance? Is there interoperability between java.awt.Graphics2D and javafx.scene.canvas.GraphicsContext?

Or, if not between Graphics2D and GraphicsContext directly, is there any means of displaying a Graphics2D render in a JavaFX application analogous to say Swing displaying Graphics2D renders in Panels?

Background

If not obvious from the question, I'm fairly new to the Java ecosystem. For more context, most things that I'm finding in internet searches are examples/tutorials explaining how things done in AWT can be done in JavaFX (see Example Article), which doesn't answer my question, but does lead me to conjecture that there is no interoperability. However, I'm hoping someone more familiar with the ecosystem can answer the question outright.

Answer

jewelsea picture jewelsea · Jun 12, 2013

There is no built-in interoperability between an awt Graphics2D and a JavaFX GraphicsContext, they are completely separate APIs for completely separate UI toolkits.

Recommendation

Is there a requirement to modify or plug into an existing Swing application?

Yes => Code to the java.awt.Graphics interface and (when embedding in JavaFX) wrap your awt rendered graphics in a SwingNode, or use a bridge as defined below.

No => Code direct to a JavaFX graphics context or the JavaFX scene graph.

Displaying Swing (and AWT) in JavaFX

To display Swing in JavaFX, you can use a SwingNode, which is available in a Java 8 early access release.

Displaying JavaFX in Swing

To display JavaFX in Swing, you can use a JFXPanel. Place your JavaFX canvas into the JFXPanel. See the JavaFX for Swing Developers tutorial for more information.

Bridging AWT and JavaFX Graphics

You could implement a bridge pattern to develop an abstract interface and then delegate to a configured Graphics implementation. The wiki page I linked provides a very good example of how this may be done. I think the implementation of such a bridge would be quite straightforward. For instance, you could implement java.awt.Graphics and map the api calls to JavaFX GraphicsContext operations. Once your bridge is complete, you just code to the bridge interface and the bridge translates your api calls to thread-safe invocations of awt or javafx methods as appropriate depending on your chosen implementation.


Update: May 20, 2014

David Gilbert (JFreeChart creator) created a bridge. The project is FXGraphics2D:

FXGraphics2D is a free implementation of the Graphics2D API that targets the JavaFX Canvas. The code has been developed for the use of Orson Charts and JFreeChart, but will be generally useful for any code that uses the Graphics2D API.

FXGraphics2D requires JDK 1.8.0 or later and is licensed under the terms of a (three clause) BSD-style license.

FXGraphics2D home page and github location.


Threading Advice

Be careful of how you manage threads if you are mixing JavaFX and Swing Code. Both toolkits are single threaded and both toolkits run their processing on their own thread, so JavaFX code must go on the JavaFX thread and Swing code must run on the Swing thread.

Consider the JavaFX SceneGraph

JavaFX includes a scene graph capable of rendering 2D shapes. Consider using the scene graph instead of a direct draw canvas.

Future Possiblities

It is likely that a future version of JavaFX might include something like an OpenGLNode, allowing you to render directly to an OpenGL buffer. An API for drawing on such a node would likely be significantly different than the JavaFX canvas API (e.g. it would use something like jogl).

A note on your linked Example Article

The article you link in your question relates to JavaFX 1.x. In general, completely disregard all old articles related to JavaFX 1.x as it is totally obsolete and any information in such articles may confuse you greatly.

Articles related to JavaFX 2+ are relevant and the best source for them is the official Oracle JavaFX 2 documention.