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.

We have not yet provided a SplitView Control in JavaFX (and it is not in the plan for 1.3). However, the main reason is that it is relatively simple to write one from scratch so we’re focusing on some of the harder things (like TreeViews). I was asked recently how to go about writing a SplitView in JavaFX, so I decided to write a very short blog post with sample code from a demo I wrote for this past Devoxx.

Essentially what I did was to create a specialized Container. (Note, if we were doing this in the core platform I’d make it a Control so that it is skinnable, but in my case this was lower overhead for something specialized I was doing). It consists of a “left” and “right” side (vertical splits would be similar and is left as an exercise to the reader!). It then has a transparent rectangle which is used as the divider, and on which we place the mouse events. Whenever the divider is dragged around, the SplitView is marked as needing to be laid out. Whenever layout occurs, the left & right sides are resized to fit relative to the divider. Here’s the code (which I have not sanitized so there may well be bugs!)

[jfx]
public class SplitView extends Container {
public var left:Node;
public var right:Node;

var pressX:Number;
var initialX:Number;
var divider:Rectangle = Rectangle {
blocksMouse: true
x: 200
y: 0
width: 5
cursor: Cursor.H_RESIZE
fill: Color.TRANSPARENT
onMousePressed: function(e) {
initialX = divider.x;
pressX = e.sceneX;
}
onMouseDragged: function(e) {
var delta = e.sceneX – pressX;
divider.x = initialX + delta;
requestLayout();
}
}

override var content = bind [left, divider, right];

override function doLayout() {
// layout the left node such that it fits up to divider.x
layoutNode(left, 0, 0, divider.x, height);
divider.height = height;
layoutNode(right, divider.x + 5, 0, width – (divider.x + 5), height);
}
}[/jfx]