I am wondering the same. I'm using the current version of javaFX SDK (1.1.1) and I don't know how to handle multithreading "by hand". I could read some examples with "do" and "do later" statements which don't exist anymore. We also can't invoke a thread directly, using a class extending Thread and calling the method start().
I have several Timeline variables running in a CustomNode, and when I want to bind a simple Integer updated every second then displayed, my display thread (the Timelines) are totally frozen every seconds for a few milliseconds, then move again. Multithreading seems to be automatically handled or it's well hidden, at least from my sight.
Suite...
The AbstractAsyncOperation use FutureTask
If you want use Thread in your programm:
You have to use Runnable because Thread is not supported
Execute it in a ExecutorService for exemple.
If you handle bound variable in your Thread, make a local copy of your variable for your Runnable to use it.
After task completion, to refreshing your variable update it in a FX.defererAction function
FYI, Alex, you have an Edit button (for a limited time) on the top-right corner of each of your answers. :-)
Not sure if you can delete your duplicate post, though (at best you can trim it down).
There is correction instead Integer you have to use Duration.
Here is the code.
var timer:Timeline = null;
public function scheduleAction(timeout:Duration,action:function()) {
var timer: Timeline = Timeline {
repeatCount: 1
keyFrames: KeyFrame {
time: timeout
action: action
}
}
timer.play();
}
You can use this like this
scheduleAction(5s, function () { <<your action here >> }
I'm currently using the Timeline trick in order to thread a few animations. Everything is fine as long as I don't use any binding operation into another Node of the scene! Here is the wierd behavior:
My scene has two CustomNode, one performing 3 Timeline animations at the same time within a single Timeline called every second, and another one displaying a simple digital watch with the current time updated every second too. I added a draggable behavior to the 2nd CustomNode.
When I start the application, whenever the 2nd node (the digital watch) is refreshed (simple Text component binded on a local attribute), the 1st Node's animations are frozen. It's like the binding is blocking the Timelines from the other Node. But! If I move the 2nd Node over the 1st one, no more freezes!.
Here is some code, I omitted a lot to focus on the threading part only:
The 1st Node animations:
init {
var timeline = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames : [
KeyFrame {
time : 1s
canSkip : true
action: function() { (m_layerList[1] as TracksLayer).refreshTracks(); }
}
]
}
timeline.play();
}
public function refreshTracks(): Void {
[...]
for (track in tracks) {
[...]
// On anime la piste.
var anim = Timeline {
repeatCount: 1
keyFrames : [
at(1s) {
trackNode.track.translateX => tmpPos[0] tween Interpolator.EASEBOTH;
trackNode.track.translateY => tmpPos[1] tween Interpolator.EASEBOTH;
}
]
}
anim.play();
}
}
}
The 2nd Node displaying time:
init {
var timeline = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames : [
KeyFrame {
time : 1s
action: function() { nextTick(); }
}
]
}
timeline.play();
}
public function nextTick() {
now = Calendar.getInstance();
m_time = "{now.get(Calendar.HOUR)}:{now.get(Calendar.MINUTE)}:{now.get(Calendar.SECOND)}";
}
var dateEV = EVNode {
m_EVModel: EVModel {
m_width: m_width
m_height: m_height
m_title: bind "{m_date} - {m_time}" // The evil binding!
}
}
Oh my god! I just figured out where it came from. That was not related to any multithread issue or something, it was only the fill property of my CustomNodes. I was using a LinearGradient, and when it's applied to a big area such as my digital watch on the right (500 x 1200), it slows down everything. I simply removed this gradient and the freezes were gone.
In order to get rid of this issue AND to keep my nice LinearGradient, I had to set the "cache" property to "true". If not, it seems that each time the node's content is updated, the whole LinearGradient is drawn again, which leads to the freezes.
There is a big missunderstanding about this post:
Use of TimeLine is NOT a way to to real Threading, it just allow to handle simply graphic stuff.
Test a very long and intensive task in a TimeLine, you should see the UI less responsive, worst test a blocking task like I/O in a TimeLine, you should be surprised.
If you profile your javaFX app you can see a specific pool wich handle TimeLine, etc.
So the only way to do REAL multithreading in JavaFX is using java Thread API with Runnables and updating UI throw EventQueue.invokeLater() or FX.deferAction()