### JavaFX and Collatz Conjecture…

March 23, 2010

Following on from my previous posting about multi-threading I wanted to share with you a little “toy” I recently wrote. Upon understanding how to implement threading into JavaFX I wanted to write up an example to help me get a good understanding. I decided I would visualise Collatz Conjecture, feeling it was a perfectly simple principle that I could animate.

Firstly, for those of you who are not aware, Collatz Conjecture is nice and simple to perform. You take any natural number (N) and if it is odd then multiple it 3 and add 1, and if it is even divide by 2. This continues until you reach the number 1, below is a table of two examples for the natural numbers 4 and 5:

 N = 4 N = 5 4 is even so 4/2. N = 2 5 is odd so 5*3 + 1. N = 16 2 is even so 2/2. N = 1 16 is even so 16/2. N = 8 8 is even so 8/2. N = 4 4 is even so 4/2. N = 2 2 is even so 2/1. N = 1

It isn’t really rocket science is it? It is quite interesting though. Try the number 27. There is more information on this available at, unsurprisingly, Wikipedia.

With that dealt with lets go back to the animation. I decided I wanted to animate this process, in fact I wanted each number to roll across the screen as it iterated through all of the numbers. As this idea progressed in my mind I happened across the thought that I could make it like a pack of cards being dealt. However the twist was the area of the screen number would land in would be determined by its value:

The final positioning (X,Y) of each rectangle, or card, is down to random positioning. This would give you a rather crude distribution.

Each card will rotate across the screen to its destination, one after the other (as if it had been dealt their). Hence I employed the threading logic as defined in my previous post, with each toss of the rectangle taking around 0.5 seconds to rotate and position itself across the screen.

All you, the user, need do is enter a number, watch the numbers being dealt across the screen and titter at the simplisity, oh and select again if you want to watch another number 🙂

Have a look, what do you think?

If anyone is interested I could go into more detail about the code?

JavaFX Applet

### JavaFX – Multi-Threading and updating a shape in a scene with a controlled delay

March 18, 2010

I came across a posting on the JavaFX general forum. I was intrigued by what the person was looking for, and by the suggested result. I decided to write my own solution, although I was too late to help the person as the others had already made suggestions. I prefer mine 🙂 Further to this, the problem posed by the person was similar to the problem I was having.

The Problem:

They want to update the width of a rectangle every second, based on a random value. This update should be a smooth animation, so it would be similar to sliding doors (in my mind anyway).

The initial response was to use Timelines to complete this. Now, I know that JavaFX is single threaded, but I am unable to make this work using Timelines (I was guessing two embedded Timelines). However I could not get this to work in a controllable manner and so started searching the web knowing I need to implement multi-threading behaviour.

The basic theory here is you create a process / thread / task (whatever you want to call it) that will go off and get you the data you are looking for (in this case a random number which will be mapped to the rectangle’s width). Whilst in the process of getting this data you put the process to sleep, that is so there is a delay in you receiving the data. When you receive this data you can apply it to the rectangle, in this case, and at the same time apply the animation which will create the sliding door effect (this is my own interpretation of the effect).

To do this we need to create Java classes, a Java Interface, and JavaFX file.

In the first place create the class which performs the task, in this case the random number generation for the width:

SusantData.java

```public class SusantData
{
int value = 0;

public double getSusantValue()
{
return 25 + java.lang.Math.random() * 50;
}
}
```

With that done, we now need to create our process / thread / task class. This class actually controls the processing of the
thread, you start, pause and detect the status of the thread through this class. This is a JavaFX class, not a Java class.

```public class MyTaskSusant extends JavaTaskBase, Progressable
{
public-init var rData: SusantData;
var peer: MyRunnable;

override function create(): RunnableFuture
{
peer = new MyRunnable(rData, this);
}

override function setProgress(pro:Long)
{
progress = pro;
}

override public function start():Void
{
progress = 0;
super.start();
}
}
```

Ok, so we have the task class setup, we now need to create an interface which will be used by both our task class and thread, it is quite straight forward. This method allows us to update the progress of the thread between the two classes. You will have noticed that the task class implements both the interface and JavaTaskBase.

Progressable.java

```public interface Progressable
{
void setProgress(long progress);
}
```

The final class, MyRunnable directly controls the thread. Here we define the code around the run statement, and one of the most important bits is to put the thread to sleep to introduce our one second delay. In this case we simply get our random value and update the setProgress. In this example I want the width, I.e the random number, of the rectangle to change / morph / slide 100 times and hence placed the loop within the run method. You will notice, also, that within setProgress FX.deferAction() is used to invoke the threads setProgress because all events have to be dispatched in EDT (Event Dispatch Thread).

MyRunnable.java

```public class MyRunnable implements RunnableFuture
{
SusantData rValue;

public MyRunnable(SusantData rdata, Progressable pi)
{
rValue = rdata;
}

public void run() throws Exception
{
for (int i = 0; i < 100; i++)
{
Double t = rValue.getSusantValue();
System.out.println("susantValue is now "+t);
setProgress(t.intValue());
}
}

void setProgress(final long progress)
{
javafx.lang.FX.deferAction(new Function0<Void>()
{
public Void invoke()
{
return null;
}
});
}
}
```

Now we have set all the “background” code up, we need to code the “stage” making reference to this code. Here is the main.fx, were we are instantiating the classes (SusantData and MyTaskSusant) and then define our objects (shapes etc). I have commented the code to try and explain what I am doing:

main.fx

```var s:  SusantData = SusantData{};

var width: Integer = 10;
var rect : Rectangle = Rectangle
{
width: width     //Initial start value
height: 10;
fill: Color.PINK;
translateX: 100;
translateY: 60;
}

var t: Timeline;

//This is a trigger, everytime the progress value
//changes, which is the random number
//generated by SusantData then the trigger is
//started. In the first instance it checks
//that the value generated is greater than 0
//(because this will occur at start up -
//own preference here).
//
//When the value of st is greater than 0 we create
//the Timeline instance which references
//rect, defines the time to run (1 second) and states
//that it should take the rectangle's
//width from its current value to the random
//value generated. This animation should EASEBOTH
//which is it slow to start and finish.
//
//With that complete, we play the Timeline and then
//set the rectangle's width to the new value.
//
var st = bind susantTask.progress on replace
{

if (st > 0)
{
t = Timeline
{
def temp = rect;

keyFrames:
[
KeyFrame
{
time: 1s
values:
[
tween Interpolator.EASEBOTH
]
}
]
}
t.playFromStart();
rect.width = st;
}
}

// My stage onto which the sliding door performs.

Stage
{
title: "Async Sample"
scene: Scene
{
width: 300
height: 100
content:
[
VBox
{
content:
[
//Text to display the value of the
//random number generated.
HBox
{
content: Text
{
translateY: 50
font: Font { size: 16 }
x: 50
y: 90
content: bind
}
}
]
},
HBox
{
content:
[
//The start button to get this
HBox
{
content:
[
Button
{
translateX: 10
translateY: 10
text: "Start"
action: function()
{
{
rData: s
onStart: function()
{
println("Starting");
}
}
}
}
]
},
//The cancel button, which
HBox
{
content:
[
Button
{
translateX: 110
translateY: 10
text: "Cancel"
action: function()
{
}
}
]
}
]
},
//The sliding door, well sort of,
//which is updated by the st trigger
Group
{
content: bind
[
rect
]
}
]
}
}
```

Have a play, what do you think?