Friday, November 20, 2009

GUI development and Java FX

I hate GUI development. I'm sure lots of developers feel exactly the same way. Even if you are gifted with a sense of aesthetics that allows you to appreciate how Finder or Windows Explorer are superior to a command-line, you might still hate GUI development.

One of the reasons for this could be the difficulty of getting from a paper UI mockup to something that actually works. I've often found programs with UI design that I appreciate, but the work required to duplicate the approach is often insurmountable.

Consider the tools developers generally have at their disposal. Most, if not all of them, are very good at building applications that conform to an aesthetic that (as far as I can remember) comes from Windows 95. I'm talking about the single, resizeable window, menus, dialog boxes maybe a tool bar or 2 or 3 and a big blank space in the middle where your work goes. The best tool I've used for this kind of UI design is Qt Designer. But this doesn't help you if you want animation, or zooming or free-form layout. As soon as you go out of the standard UI box you need to build almost everything yourself. And that sucks.

Java FX seems to be one of a few tools gaining popularity these days that help us break out of the old paradigm. Consider the following code snippet. It defines an object that can be used as an arbitrarily large surface and defines a viewport onto it so that the user can drag their view around instead of dragging the objects on the view around.
public class Viewport extends CustomNode {
    public var viewWidth :Float;
    public var viewHeight :Float;
    public var content :Node[];

    var currentX :Float = 0;
    var currentY :Float = 0;
    var dragStartX :Float = 0;
    var dragStartY :Float = 0;

    def viewport = Rectangle {
        x: bind -currentX
        y: bind -currentY
        width: bind viewWidth;
        height: bind viewHeight;
        fill: Color.TRANSPARENT;
    };

    override function create() :Node {
        insert viewport before content[0];

        return Group {
            content: bind content;
            translateX: bind currentX;
            translateY: bind currentY;
        }
    }

    override var onMousePressed =
        function(event :MouseEvent) :Void {

            dragStartX = event.sceneX + currentX;
            dragStartY = event.sceneY + currentY;
        };

    override var onMouseDragged =
        function(event :MouseEvent) :Void {

            currentX = dragStartX - event.sceneX;
            currentY = dragStartY - event.sceneY;
        };
}

I doubt that can be done as easily, quickly and readably in Qt or Apple's Interface Builder. That viewport class took about 1 hour to code. Now lets say you want to drag the widgets around on the viewport, no problem, just put them in a DraggableGroup like this one.
public class DraggableGroup extends CustomNode {
    public var content :Node[];

    override def blocksMouse = true;
    var currentX :Float = 0;
    var currentY :Float = 0;
    var dragStartX :Float = 0;
    var dragStartY :Float = 0;

    override function create() :Node {
        return Group {
            content: bind content;
            translateX: bind currentX;
            translateY: bind currentY;
        }
    }

    override var onMousePressed =
        function(event :MouseEvent) :Void {

            dragStartX = event.sceneX - currentX;
            dragStartY = event.sceneY - currentY;
    };

    override var onMouseDragged =
        function(event :MouseEvent) :Void {

            currentX = event.sceneX - dragStartX;
            currentY = event.sceneY - dragStartY;
    };
}

Although this isn't particularly exciting, it does show that with some basic built-ins you can create a GUI that would be quite hard to put together in one of the stalwart toolkits developers normally use, although you're in trouble if you want multi-line text editing!

Sunday, November 15, 2009

Java FX and the Yield Slope

Recently I've been looking at Java FX, a promising new technology from Sun that is supposed to help developers create rich web applications, desktop applications and mobile applications.

While Java FX 1.2 can't live up to that promise just yet, it is nonetheless fun to use. The biggest missing component is a design tool. The FX community is abuzz with the possibility of this gap being bridged in the next version, hopefully to be released sometime soon. Some early screen-shots can be seen here.

On the plus side, Java FX (on the desktop) has access to the full class library of Java SE. Unfortunately, this isn't true for the browser or mobile versions (for obvious reasons.) For those configurations, we have to wait for the default Java FX class library to grow.

The following is a simple (and ugly - GUI design isn't my forte) Java FX application that graphs the yield slope over the last 30 years.


 Click the image to run the program