Real newbie to the JavaFX scene so here goes.
griffon 1.4.0 - jdk 1.7.0_45
griffon plugins ( groovyfx-0.9.1, javafx-0.10.0)
I'm trying to implement a simple focus listener to one of my textfields. The idea is that once the textfield is focused I want to change the message of a label within the same view. I'm sure the answer is simple but I think I've over complicated matters.
For overall context, I'm trying to implement my views by reading in fxml and using the groovy view for binding and such.
application(title: 'Myapp', sizeToScene: true, resizable: false, centerOnScreen: true) {
scene(fill: WHITE) {
fxml(app.getResourceAsURL('fxtemplates/login.fxml').text) {
// my bindings and onActions ( which are working great ) go in here
}
Looking at the groovyfx docs there doesn't appear to be a method for onFocus like that of onAction and such so I have to add a listener to the focusedProperty - great no sweat. I first tried writing a closure for the ChangeListener :
aTextField.focusedProperty().addListener({ obsVal, oldVal, newVal ->
// do something...
})
But Uberbuilder complained and I'm obviously doing that wrong ( a nudge in this direction would help )
So I wrote an empty FocusListener Class that implements a ChangeListener and then bound that in my view.
class FocusListener implements ChangeListener<Boolean> {
@Override
public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldVal, Boolean newVal ) {
// for the view to override...
}
}
Then in my view
aTextField.focusedProperty().addListener(new FocusListener () {
@Override
public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldVal, Boolean newVal ) {
if(newVal != null && newVal == Boolean.TRUE) {
execInsideUIAsync {
println 'focus gained'
}
}
}
});
The code executes just fine ( focus gained prints ) but of course I'm down in scope so I don't have access to my controller or view components. For grins ( not really liking it but trying it out ) I passed in my controller to the constructor of my FocusListener and called a method on my controller.
class FocusListener implements ChangeListener<Boolean> {
def controller
public FocusListener(controller) {
this.controller = controller
}
@Override
public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldVal, Boolean newVal ) {
// for the view to override...
}
}
and then in my view
aTextField.focusedProperty().addListener(new FocusListener (controller) {
@Override
public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldVal, Boolean newVal ) {
if(newVal != null && newVal == Boolean.TRUE) {
println "Gained Focus"
execInsideUIAsync {
println 'focus gained'
controller.&clearMessages
}
}
}
});
Nothing complained but my controller method never exectued ( nothing complained either, the output was 'focus gained'. In my debugger I do see a reference to the controller... but at this point, I'm down the rabbit hole and sure of an incorrect implementation...
Could someone please help me?
Thanks!
Ok - so after more tinkering around ( and a good run ). It's quite easy.
In the view I added a listener to the focusedProperty of the textfield. That listener is referenced in the model thus :
aTextField.focusedProperty().addListener(model.fieldFocusListener)
then in the model I implement changes to the already bound values
@FXBindable String field_one
@FXBindable String field_two
@FXBindable String message
//...
ChangeListener fieldFocusListener
void mvcGroupInit(Map args) {
fieldFocusListener = new ChangeListener() {
@Override
void changed(ObservableValue observableValue, Object t, Object t1) {
this.setMessage('your message here')
}
}
}
Which makes total sense to me in the model as I have all the access I need to manipulate my view. Anyway, I hope this helps someone else in need.