Holds a master degree in Computer Science. Has a 6 years work experience doing front end development which has also implied self improving on areas like Design and User Experience. Pedro has posted 32 posts at DZone. You can read more from them at their website. View Full User Profile

Integrating JavaFX and Swing (Revised)

06.18.2013
| 5427 views |
  • submit to reddit


I’ve just finished rewriting a component of my app that was using Swing and now is using JavaFX, I’ve ended up with a JavaFX component that integrates with the larger swing app. It is a large app and the rewrite took me a while, in the end everything worked fine and I’m glad I did it.

Reasons you might want to do this in your swing app

You might want to rewrite your Swing app and change it to use JavaFX instead, the easiest way is to do this incrementally by changing each component at a time. This requires that you integrate each of the newly changed JavaFX components with the rest of your Swing app.

I’ll summarize why you might want to start rewriting your app from Swing to JavaFX:

  • It’s the future

Swing is pretty much dead in the sense that it won’t get any further developments. JavaFX is the new UI toolkit for Java, it is better prepared for the future with things like touch support, 3D, built-in animation support, video and audio playback, etc.

  • Probable future support for mobile: Android, IOS…

There is already a working prototype that enables you to port javafx apps to IOS called RoboVM – http://www.robovm.org/. As more and more of JavaFX gets open sourced the better RoboVM will get, with this open sourcing probably other utilities will arise that will enable ports to other environments.

  • It’s solid

JavaFX is a well-designed toolkit with a rapid growing pace, a bright future and a set of good free UI tools. Furthermore, unlike in the past, Oracle is giving developers feedback a great importance changing and adapting its APIs to meet their goals.

  • It’s pretty

Unlike Swing, not counting third party librarys, which was ugly by itself, JavaFX looks good right from the start, especially the new Modena skin coming to JavaFX 8: http://fxexperience.com/2013/03/modena-theme-update/- . Given that users nowadays expect good looking, well designed apps this is a pretty good point.

  • Nice extras

Some nice extras, like the charts API, an embedded browser that supports HTML5, etc.

How you do it

Back on JavaFX 1.3 you could embed Swing in JavaFX but not the other way around, at least not officially. I implemented a Swing component that allowed you to embed JavaFX content in Swing (called JXScene) and made it publicly available in the jfxtras project. It was the only way you could embed a JavaFX scene in a Swing app.

Now Oracle with JavaFX 2.X made an official way of embedding JavaFX in Swing which makes more sense but unfortunately not a way to embed Swing in JavaFX, I guess this will suffice in most cases. However, with the coming JavaFX 8 you’ll also have the ability to embed a swing component in a JavaFX app with the Swing Node.

ARQUITECTURE

Essentially when you are embedding JavaFX in Swing you end up with 2 running UI threads: the Swing EDT thread and the JavaFX User thread.

There is a chance that in the future there will only be one thread for both as is the case with SWT, making Swing run on the JavaFX User Thread, but for now we’ll have to manage our way with 2 threads.

Two threads running at the same time in the UI is what complicates matters, and makes JavaFX integration not as easy as you might expect, unless you’re doing some trivial small app but I guess that is not the scenario for most of the real world use cases. If you’re doing a small app might as well do it all in JavaFX.

CODING

JavaFX gives you JFXPanel, which is a Swing panel that hosts a JavaFX scene. You set the scene on the JFXPanel and add the panel wherever you could add a Swing Component.

To access JavaFX data you have to wrap your code in a Runnable object and call the Platform.runLater method:

jbutton.addActionListener(new ActionListener() { 
 public void actionPerformed(ActionEvent e) { 
 Platform.runLater(new Runnable() { 
 @Override
  public void run() {
  fxlabel.setText("Swing button clicked!"); 
 }
  });
  }});

On the other side is Swing data. This data must be accessed only by the EDT. To ensure that your code is running on the EDT, wrap it into a Runnable object and call the SwingUtilities.invokeLater:

SwingUtilities.invokeLater(new Runnable() {
  @Override
  public void run() {
  //Code to change Swing data.
  }
});

Tips

  1. JavaFX already throws exceptions when you access a JavaFX resource outside the JavaFX User Thread, but bear in mind that this does not happen always. To minimize performance costs not all situations are checked.
  2. If you use Substance (in my opinion without any doubt the best looking free look and feel for swing) third party library than an exception will also be thrown whenever a Swing resource is accessed outside the EDT. Setting Substance as your Swing look and feel might be a good solution to lessen concurrency mistakes on the swing side that you might do.
  3. Be very careful when sharing resources between the 2 UI threads, try to avoid this as much as possible. Best way to solve multi-threading problems is to avoid them, and these kind of problems are among the most difficult to solve in Software Engineering. There is a reason why Swing started off as a multi-threaded toolkit and ended changing to a single threaded one.
  4. Sometimes you might want to check if you are on the JavaFX User Thread via Platform.isFxApplicationThread() and only than issue a call to Platform.runLater(…), because if you are on the JavaFX User Thread and call runLater(...) the execution of the code that is inside will still be deferred to a later time and this might not be what you want.
  5. There are a lot of JavaFX controls that cover their swing counterpart, however they are different and have different features that you must adapt to. There are also some controls like the JFormattedTextField that don’t yet exist. In conclusion JavaFX is different from Swing. Has different controls and a different arquitecture and API that you must adapt to.
 Other links to check out:
Published at DZone with permission of its author, Pedro Duque Vieira. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Peter Henderson replied on Tue, 2013/06/18 - 4:33pm

Call me a cynic but I'd hazard a guess that business applications are what fund many developer jobs, and they fall into java+html or java+swing camps. (Yes I am over generalizing here ;-)

As far as I can see, javafx provides none of the basic building blocks a business app needs. You know things like, date fields, number fields, field validation etc. etc. being able to play the latest video format is nice and looks good for demos, but as my brother says "Bullshit baffles brains".

So now javafx is being joined with swing. Great maybe some of the many bugs will get fixed. I somehow doubt it though. It is more like: "Hey swing has a bunch of nice features, let's use it to demo something, oh you really wanna use it? on real paying customers? Tough it's still got all the swing bugs."


For me the writing has be on the wall. I've spent the last 3 years porting a huge swing app to an interwebs thingme. Not been easy but I'm over the hill and coasting down to the finish line. So long swing (and client java) we had fun, hello html+js (and still the same server side business engine)


my 10pence worth.
Good luck to the folks who do.



Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.