FX Experience Has Gone Read-Only

I've been maintaining FX Experience for a really long time now, and I love hearing from people who enjoy my weekly links roundup. One thing I've noticed recently is that maintaining two sites (FX Experience and JonathanGiles.net) takes more time than ideal, and splits the audience up. Therefore, FX Experience will become read-only for new blog posts, but weekly posts will continue to be published on JonathanGiles.net. If you follow @FXExperience on Twitter, I suggest you also follow @JonathanGiles. This is not the end - just a consolidation of my online presence to make my life a little easier!

tl;dr: Follow me on Twitter and check for the latest news on JonathanGiles.net.

Yuck, ‘CheckBoxTreeView’ – what a mouthful. Anywho – I was just looking at a very interesting JavaFX session slidedeck from Jazoon presented by AdNovum Informatik AG titled ‘JavaFX – The Condemned Live Longer‘. It is a great slide deck as they are a company that have invested a lot of time researching the available RIA technologies, and they are pretty upfront with what they like and don’t like in JavaFX, and what their developer experience has been.

One of their comments was that they wish JavaFX had a CheckBoxTreeView. Seeing as I developed the TreeView control in 1.3 I thought I might be in a good position to answer their wish. What I’ve got here today is not perfect, but then it only took 10 minutes to create (in fact this blog post is taking me longer to write!). This is also not a complete example – you’d want to improve it to allow for the state to be set based on a value contained within the cell item, rather than just ‘floating’ as it does here – you’ll get scrolling oddities if you just use the code below as-is.

Here is the code you should add to your project:

[jfx]
import javafx.geometry.Insets;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
import com.javafx.preview.control.TreeCell;
import javafx.geometry.VPos;

public class CheckBoxTreeCell extends TreeCell {
public var onSelected:function(item:Object, selected:Boolean):Void;

var checkBox:CheckBox;
var cbSelected = bind checkBox.selected on replace {
onSelected(item, cbSelected);
}

override var node = HBox {
padding: Insets { left: 7 }
nodeVPos: VPos.CENTER
content: [
checkBox = CheckBox { }
Label {
text: bind if (item == null) then "" else
if (item instanceof String)
then item as String else "{item}";
}
]
}

override var onUpdate = function() {
disclosureNode.visible = not empty and not treeItem.leaf;
}
}
[/jfx]

To use this class, just do something like the following:

[jfx]
var tree = TreeView {
root: …
cellFactory: function():TreeCell {
def cell:TreeCell = CheckBoxTreeCell {
onSelected: function(item:Object, selected:Boolean) {
println("Toggled {item} to {selected}");
}
}
}
}
[/jfx]

You’ll see in this code snippet we are using our CheckBoxTreeCell class, and define an onSelected function callback to be informed when the selection of the CheckBox changes. Of course in your implementation you should do something more useful than just doing a println 🙂 .

In my test program, I get the following appear on screen:

So, there we go. It’s not entirely perfect – I haven’t bothered to perfect the alignment and positioning (it could do with some tweaking). I’m also not completely happy with the onSelected function name, but this is trivial to reconsider at a future date. I hope that perhaps this is helpful to some people, and perhaps we can integrate something like this into a future release of JavaFX – but no promises on that front. Finally, I hope it shows just how powerful the cell architecture is in JavaFX ListView and TreeView controls.