JavaFX

From APIDesign

(Difference between revisions)
Jump to: navigation, search
(Dispatch Threads)
(Dispatch Threads)
Line 3: Line 3:
=== Dispatch Threads ===
=== Dispatch Threads ===
-
Up until today (e.g. May 2012) mixing [[Swing]] and [[JavaFX]] was not easy because each of these two systems used its own dispatch thread. Whenever one needed to operate with [[Swing]] one had to enter the dispatch thread by using {{JDK|java/awt|EventQueue}}.invokeLater({{JDK|java/lang|Runnable}}). As soon as there was a need to manipulate with [[JavaFX]] components one had to use {{FX|javafx/application|Platform}}.runLater({{JDK|java/lang|Runnable}}). As [[Java]] is not very good at this kind of actor based coding, the result was completely unreadable code full of deeply nested {{JDK|java/lang|Runnable}}s:
+
Up until today (e.g. May 2012) mixing [[Swing]] and [[JavaFX]] was not easy because each of these two systems used its own dispatch thread. Whenever one needed to operate with [[Swing]] one had to enter the dispatch thread by using {{JDK|java/awt|EventQueue}}.invokeLater({{JDK|java/lang|Runnable}}). As soon as there was a need to manipulate with [[JavaFX]] components one had to use {{FX|javafx/application|Platform}}.runLater({{JDK|java/lang|Runnable}}). As [[Java]] is not very good at this kind of [[wikipedia:Actor_model|actor]] based coding, the result was completely unreadable code full of deeply nested {{JDK|java/lang|Runnable}}s:
<source lang="java">
<source lang="java">
Line 27: Line 27:
}
}
</source>
</source>
 +
 +
I am proud to announce that the mutual [[Swing]] and [[JavaFX]] interoperability has been greatly simplified during May 2012. No need for massive amount of asynchronous {{JDK|java/lang|Runnable}}s! Your [[Swing]] code can directly talk to [[JavaFX]] data structures and your [[JavaFX]] code can do the same to [[Swing]] objects. This is a [http://source.apidesign.org/hg/jdk/rev/4ed8674de305 small change], but huge step forward for [[Swing]]+[[JavaFX]] interoperability!
 +
 +
The basic idea is to share the [[Swing]] and [[JavaFX]] dispatch threads. Trivial implementation would keep the ''AWT-EventQueue-X'' and just made sure one will always use {{FX|javafx/application|Platform}}.runLater to dispatch the [[Swing]] events. More advanced implementation can even eliminate the need for ''AWT-EventQueue-X'' thread completely (as the [http://source.apidesign.org/hg/jdk/rev/4ed8674de305 patch] shows). By running the event processing in the same thread, it is safe to access [[Swing]] as well as [[JavaFX]] [[API]]s directly which greatly simplifies the coding model.
 +
 +
I've send my patch to Artem (Oracle's [[JavaFX]] guru) as a sketch of what could be done and the news from Artem are really great. The basic interoperability seems to work fine. Originally I was slightly afraid whether processing of events in different thread will work seamlessly, but now (when it has been experimentally verified) I think the changes have always been high for this system to work well.
 +
 +
When your code is running (handling a [[Swing]] event) how can you tell in which thread it is running? Of course, there is {{JDK|java/lang|Thread}}.getName(), but beyond that, there is no other way for your code to find out that now, it runs in {{FX|javafx/application|Platform}}.runLater thread. All event processing remains synchronized (no code runs in parallel), so how could your code tell it is running in different thread? No chance, that is why I believe this change is completely safe.
 +
 +
I am not sure in which version of [[JavaFX]] this improved interoperability will be available (it requires changes on the [[JDK]] side as well), but I hope that it lands at least in [[JDK]]8. I am looking forward, as that will greatly improve life for guys trying to mix [[Swing]] with [[JavaFX]].
 +
 +
<comments/>

Revision as of 10:22, 23 May 2012

JavaFX is new, modern UI toolkit for rendering Java UIs. The idea is tempting - instead of bloated AWT and Swing on top, one can use a completely independent UI and lightweight library instead. However, as usual when offering AlternativeBehaviour, the problem is co-existence - there a tons of Swing applications around and they need to migrate to JavaFX in an incremental fashion. Unless such migration is smooth, people will rather stick with what they have right now.

Dispatch Threads

Up until today (e.g. May 2012) mixing Swing and JavaFX was not easy because each of these two systems used its own dispatch thread. Whenever one needed to operate with Swing one had to enter the dispatch thread by using EventQueue.invokeLater(Runnable). As soon as there was a need to manipulate with JavaFX components one had to use Platform.runLater(Runnable). As Java is not very good at this kind of actor based coding, the result was completely unreadable code full of deeply nested Runnables:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
             JFrame frame = new JFrame("FX");
             final JFXPanel fxPanel = new JFXPanel();
             frame.add(fxPanel);
             frame.setVisible(true);
 
             Platform.runLater(new Runnable() {
                 @Override
                 public void run() {
                     // This method is invoked on JavaFX thread
                     Scene scene = createScene();
                     fxPanel.setScene(scene);
                 }
             });
        }
    });
}

I am proud to announce that the mutual Swing and JavaFX interoperability has been greatly simplified during May 2012. No need for massive amount of asynchronous Runnables! Your Swing code can directly talk to JavaFX data structures and your JavaFX code can do the same to Swing objects. This is a small change, but huge step forward for Swing+JavaFX interoperability!

The basic idea is to share the Swing and JavaFX dispatch threads. Trivial implementation would keep the AWT-EventQueue-X and just made sure one will always use Platform.runLater to dispatch the Swing events. More advanced implementation can even eliminate the need for AWT-EventQueue-X thread completely (as the patch shows). By running the event processing in the same thread, it is safe to access Swing as well as JavaFX APIs directly which greatly simplifies the coding model.

I've send my patch to Artem (Oracle's JavaFX guru) as a sketch of what could be done and the news from Artem are really great. The basic interoperability seems to work fine. Originally I was slightly afraid whether processing of events in different thread will work seamlessly, but now (when it has been experimentally verified) I think the changes have always been high for this system to work well.

When your code is running (handling a Swing event) how can you tell in which thread it is running? Of course, there is Thread.getName(), but beyond that, there is no other way for your code to find out that now, it runs in Platform.runLater thread. All event processing remains synchronized (no code runs in parallel), so how could your code tell it is running in different thread? No chance, that is why I believe this change is completely safe.

I am not sure in which version of JavaFX this improved interoperability will be available (it requires changes on the JDK side as well), but I hope that it lands at least in JDK8. I am looking forward, as that will greatly improve life for guys trying to mix Swing with JavaFX.

<comments/>

Personal tools
buy