Skip to content

JavaFX: binding property values to anonymous function calls

Summary: When binding to anonymous functions in JavaFX, make sure you bind to the value of evaluating the function rather than the function itself.

One of the most useful aspects of JavaFX is property binding. This allows a more declarative description of how the various UI and model components interact, and frees the user from needing to manually maintain the syncronization between them. A powerful aspect of this is to bind a property value to a value derived from calling a function with other property values.

I'm working on a small cellular automata simulator (Game of Life), which involves displaying rectangles on the screen that have a state and a color, where the color is derived from the state. The code looks like:

function state2color(b:Boolean) { if (b) { Color.SEAGREEN; } else { Color.WHITESMOKE; }}
 
class Cell {
    var state:Boolean; 
    var color:Color = bind state2color(state);
}

Because 'color' is bound to the state2color function call, it's updated any time the value of 'state' is changed. However, state2color isn't used anywhere else, so I wanted to make it an anonymous function. The first thing I tried was this:

var color:Color = bind function() { if (state) { Color.SEAGREEN; } else { Color.WHITESMOKE; }};

but I got the error:

incompatible types:
found:    function():javafx.scene.paint.Color
required: javafx.scene.paint.Color

The problem here is that I'm trying to bind the 'color' property to the anonymous function, rather than binding the property to the value of _evaluating_ the anonymous function.

The simple fix is to add parens after the function declaration, indicating that it's the return value we want:

class Cell {
    var color:Color = bind function(){ if (state) { Color.SEAGREEN; } else { Color.WHITESMOKE; }}();
}

or alternatively:

class Cell {
    var color:Color = bind function(b){ if (b) { Color.SEAGREEN; } else { Color.WHITESMOKE; }}(state);
}

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*