Closing the gap between Java and JavaFX
- May 11th, 2010
- Posted in Java . JavaFX
- Write comment
There is a huge gap between Java and JavaFX: While it is very easy to bind JavaFX objects to each other there has been no way to bind JavaFX objects to Java properties (and vice versa).
It has taken me some time to figure out how this could be solved. And at the moment I am in the progress of adding that stuff to the JFXtras project.
This will take some time until I have taken all necessary steps.
Until then i want to give you a quick jar that can be used to try that stuff…
To try it, download that jar and add it to the classpath of your JavaFX project:
bridge-1.0.0-SNAPSHOT-jar-with-dependencies
There are two ways of synchronization. At first it is possible to listen for changes to Java objects and update an JavaFX object accordingly. At the moment I have implemented two ways to listen for updates.
Java to JavaFX
- PropertyChangeEvents: This is the recommended way: Just make your Java bean fire PropertyChangeEvents whenever a property has changed.
- Busy waiting: I have added a hackish way of busy waiting. This should not be used in production code. But it offers a fast way to test things
JavaFX to Java
The reverse way has also two ways implemented:
- Calling of setters: If a JavaFX var is updated, this bridge calls the corresponding setter of your Java object (using reflection or optionally your own optimized implementation).
- PropertyChangeEvents: It is possible to create a bridge that converts the JavaFX binding
updates to PropertyChangeEvents.
With inverse…
Of course it is also possible (and most of the time necessary) to create bindings with inverse. I give you a small sample how this might work here:
We create our Java “model”:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package fxbindingtest; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; public class JavaClass { private float amount = 99; public float getAmount() { return amount; } public void setAmount(float amount) { pcs.firePropertyChange("amount", this.amount, this.amount=amount); System.out.println("Changed amount to " + amount ); } final PropertyChangeSupport pcs = new PropertyChangeSupport(this); public void addPropertyChangeListener( PropertyChangeListener listener) { pcs.addPropertyChangeListener(listener); } public void removePropertyChangeListener( PropertyChangeListener listener) { pcs.removePropertyChangeListener(listener); } } |
And here comes our JavaFX stage. This stage contains just a slider that is bound to the Java object (with inverse).
Every five seconds the model object is updated (amount+=10) – and reflected by the slider.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | package fxbindingtest; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.control.Slider; import com.cedarsoft.fx.JavaFxBridge; import com.sun.javafx.runtime.FXObject; import javafx.animation.Timeline; import javafx.animation.KeyFrame; /** * @author johannes */ var slider: Slider; //The java model class. Contains the property "amount" and a PropertyChangeSupport def javaModel = new JavaClass(); Stage { title: "Application title" scene: Scene { width: 800 height: 600 content: [ slider = Slider { min: 1 max: 100 snapToTicks: true } ] } } //Create the binding from the java model to the slider //Using the defaults: // Java --> FX: PropertyChangeEvents // FX --> Java: Calling setters by reflection JavaFxBridge.bridge( javaModel ).to( slider as FXObject ).connecting( JavaFxBridge.bind( "amount" ).to( "value" ).withInverse() ); //sorry for the stupid API - needs some polishing... //Add a timeline to simulate changes to the model Timeline { repeatCount: Timeline.INDEFINITE keyFrames: [ KeyFrame { time: 5s action: function() { println("changing amount on model"); javaModel.setAmount( javaModel.getAmount() + 10 ); } } ]; }.play(); |
And here a JNLP to run the demo (open Java Console to see the updates printed to System.out):

Disclaimer:
This is just a working-in-some-situations-prototype. It is not production-ready by far.
But if you have any comments/ideas/bugs, please mail me.
The source code can be downloaded here. But I will add that stuff to JFXtras very soon…
That’s great! It will leverage the JavaFX|Java feature, helping existing Java projects to have their View ported to JavaFX!
Thanks