Skip to main content

Learning the JavaFX way of doing things

Posted by joconner on August 10, 2007 at 11:29 AM PDT

possible javafx logoI set a challenge for myself: to port the UI of a simple application to JavaFX Script and keep all the existing application logic, models, event handlers, etc. The goal was to port just the UI and to reuse all the rest of the code. I thought it would be relatively easy to port the UI of an application without moving other code. It turns out that this isn't as easy as I once thought.

I discovered that although using JavaFX Script's declarative syntax to define the visual UI is easy, I was being simple-minded to think I'd be able to just return that whole UI structure to Java. I haven't been able to successfully pass JavaFX objects back over the Java - JavaFX Script environment boundaries.

My first problem arose when I discovered that the declarative syntax doesn't readily support naming of individual UI components. For example, look at the following JavaFX frame with a single button:

Frame {   
    content: Button {
        text: "Press me!"
    }
}

I thought I'd be able to create this UI and return the entire thing back to my Java code, then add event listeners, etc to the button on the Java side. But notice that there's no way to name the Frame's individual UI elements. In this case, that's just the single Button. Yes, the button exists; yes, it displays. However, I can't just return this whole frame and dereference the Button easily.

Then I thought that I could create a helper class to wrap the frame and to provide names for its UI elements like this:

class MyFrame extends Frame {
    attribute button: Button;
}

var myFrame = MyFrame {
    var: self
    title: "JavaFX Demo"
    button: Button {
        text: "Press me!"
    }
    content: self.button
    visible: true
};

return myFrame;

But it turns out that this return value isn't really a JFrame. Casting it over on the Java side -- where I use ScriptEngine's eval method -- just throws an exception:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: 
net.java.javafx.typeImpl.TypeFactoryImpl$ModuleImpl$ValueImpl cannot be cast to javax.swing.JFrame

So, there has to be a better way. I'm convinced of it. My initial experiments with the language suggest that although it's easy to access Java objects from JavaFX Script, using user-defined JavaFX objects from Java might not even be possible. I'm still learning, so I could be mistaken. Regardless, I'm obviously not doing this in the JavaFX way...I just have to discover exactly what that is.

Every language has its way of doing things, its own idioms, its own natural path to accomplish a goal. I think my initial goal may be constrained too much. I'm discovering that although I can call into Java to execute libraries and other business logic, it's probably best to implement all of the view and models in JavaFX. Leaving the models back in Java doesn't seem to be an effective way to use JavaFX Script.

Related Topics >>