Today, just before the end of the world (12/21/12 GMT +1 :-)), I feel like David Copperfield who would reveal a magic trick… And sometimes, the magic should stay magic… but we’re still talking about programming here, so even if I hope there are still magicians in the UI world I would apologize to all Java UI gurus, architects and evanglists who could be shocked by the current experimental approach ;-).
Ok, disclaimer done.
In the first post, you may have noticed the quote in the title when I wrote “integration” and you were right because the current implementation relies on a visual trick which consists on superposing a Swing Window on top of a JavaFX application…
As a short video:
Here are the layers:
The undecorated Swing window is synchronized with all sizes and locations of the underneath SwingNode JavaFX placeholder.
The synchronization between Swing window’s bounds and with the SwingNode placeholder was not an issue (BTW performance are quite good with a simple UI). The main problem was to ensure the Swing window to be displayed on top of the JavaFX stage. And at this time, I made it working by using the “AlwaysOnTop” property of the Swing window, which could dramatically reduce the scope of the approach.
Here is a summary of the limitations at this time:
- Limited to one SwingComponent for a JavaFX app
- “Always on top” makes the jDialog on top of Windows’ task bar
- When clicking on the Swing component, the JavaFX Stage looses the focus an so the stage window looses its drop shadow.
- Not optimal for applet mode. Offset are not good and clipping from browser must be used.
- Dealing with JavaFX and Swing threads in the same app is not trivial.
If you want to integrate into your app , simply add SwingNode.jar into your ClassPath and invoke:
Node swingNode = new SwingNode(Stage jfxStage, Component jcomponent);
The experiment is not finished. There are still some graphical artifact such as when the Swing window is stuck on top…
I also tried to implement it using multiple SwingNode into a single JavaFX application but since I currently relies on the “AlwaysOnTop” window setting this techniques is very limited, and dealing with many different windows types is not optimal for apps!
Lesson learnt: This kind of “integration” could be realistic if we could easily declare AWT windows as child of a JavaFX stage…
WORA…hum not yet ! Window management and threading seems to be slightly different on this platform ’cause my code simply doesn’t work. It throws an exception and the stage never appears… why? because http://javafx-jira.kenai.com/browse/RT-20784 Which is not related to this approach since a basic a Swing/JavaFX mixing hangs on Mac when launching from a JavaFX app (JFXPanel works fine in a Swing app on Mac)
At this stage, use this technique in case of emergency only!
(or wait for a real good integration!)