Interoperability between JavaFX and Java

Posted: December 25th, 2008 under JavaFX, JavaFX Coding.
Tags: , , ,

[ 2009/06/28 Update: Please refer to my latest article for discussion on:
Pure Java Code to Call JavaFX Class ]

From the official JavaFX blog, an article discussed the possiblity of invoking methods of JavaFX classes from Java. JavaFX can call Java code without any problem, however, the reverse is not supported by JavaFX. Doing some googling shows that programmers are trying all kinds of hacks to invoke a JavaFX class method from Java. You can check out an interesting article on reverse engineering of JavaFX classes. Even the example on JavaFX blog provided a hack to work around this.

So do we really have the need of such kind of interaction between Java and JavaFX? I’d say it is a “YES”. If Java and JavaFX can be used interchangeably(when possible), this could give more life to JavaFX in the long run. Just consider the MVC design pattern, we can write an application by using Java and JavaFX together. The “M” and “C” part can be implemented in Java while the “V” can be done by JavaFX. It would be very interesting to see this.

Right now, there are a few “standard” ways to call JavaFX from Java:

1) Using the ScriptEngineManager class. From Geertjan Wielenga‘s article, we can do it in this way:

package calc; 
 
import java.io.InputStreamReader; 
import javax.script.ScriptEngine; 
import javax.script.ScriptEngineManager; 
import javax.script.ScriptException; 
 
public class CalculatorLauncher { 
 
public static void main(String[] args) { 
 try { 
 ScriptEngineManager manager=new ScriptEngineManager(); 
 ScriptEngine engine = manager.getEngineByExtension("fx"); 
 InputStreamReader reader = new InputStreamReader
 (CalculatorLauncher.class.getResourceAsStream
 ("Calculator.fx")); 
 engine.eval(reader); 
   } catch (ScriptException ex) { 
  } 
 } 
}

However, this is just like System.exec("calc") as pointed out by cronseaux. I agree with him. A even simpler way is to use System.exec("javafx Calculator.fx") to complete the above code. So this is not a good solution.

2) Manage to use java reflection to call JavaFX class methods. This one should work because JavaFX classes are compiled into Java classes and byte code. However, the complexity makes it almost unusable and code written in this way has no readability.

3) A third approach is to define an interface in Java and implement it in JavaFX. For example,

public interface JavaInterface
{ ... }

In MyJavaFXClass.fx, do something like:

public class MyJavaFXClass extends JavaInterface
{ ... }

In you java code, just invoke the JavaFX object directly using the interface. This approach can solve most of the interoperation issues. Just that an interface is needed for every JavaFX class which is going to be called from Java. Though it is very cumbersome, at least it is the best workaround I can find so far.

Since this is the first release of JavaFX, I don’t criticize much on this given the strong powerful features of JavaFX. I do hope the future releases of JavaFX can improve on this.

[Update: Please refer to my latest article for discussion on

Pure Java Code to Call JavaFX Class]

Diecast Cars NASCAR Collectables

Online US Citizenship Practice Test

2 Comments

  • Comment by florin — January 4, 2009 @ 4:40 pm

    1

    So how would implementing a shared interface solve the problem? Should sharing the VM is implied, then what makes this a solution? Don’t you yet have to kick off the fx script via the javafx.exe?

    Dear Florin,

    To some extreme, you can start javafx first, then all other things will be transfered to Java afterwards. Like this:

    JavaMain.java
    
    public class JavaMain {
      public static Object start( JavaInterface ji){
        return ji.createStage();
      }
    }
    
    
    JavaInterface.java
    
    public interface JavaInterface {
      public Object createStage();
    }
    
    
    MyStage.fx
    
    public class MyStage extends JavaInterface {
    
      public override function createStage(): Object{
    
        Stage {
          title: "Application title"
          width: 250
          height: 80
          scene: Scene {
            content: Text {
              font: Font {
                size: 24
              }
              x: 10,
              y: 30
              content: "Application content"
            }
          }
    }
      }
    
    Main.fx
    
    var mys = MyStage{};
    JavaMain.start(mys);
    
    

  • Comment by Octavian Tanase — February 11, 2009 @ 11:02 pm

    2

    Cool blog. Now that the Sun folks have released JavaFX 1.1 – mobile edition which complements the Dec ’08 release, you should take a look at the common API (vs desktop). The APIs enable developers to deploy application on desktop, browser and JavaME enabled phones. When calling Java you have take in consideration the reduced screen real estate, as well as the fact that the CLDC/CDC profiles implements only a subset of the Java API.


RSS feed for comments on this post.