asullaherc asullaherc - 2 months ago 16
Groovy Question

How to listen focusing child event

here is my code:

@Override
void start(Stage stage) throws Exception {
def root = new VBox() {
{
children.add(new TextArea() {
{
setId("ta1")
}
})
children.add(new TextArea() {
{
setId("ta2")
}
})
}
}
root.setOnFocus(new OnFocus() {
void onFocus(Node focusedTarget) {
// handle focusedTarget
}
})
def scene = new Scene(root, 800, 600)
stage.setScene(scene)
stage.show()
}


I hope implement following code to handle focusing child events

root.setOnFocus(new OnFocus() {
void onFocus(Node focusedTarget) {
// handle focusedTarget
}
})


if i set #ta1 and #ta2's focusedProperty, if child are large, it hard to do it, so I hope directly listen the parent, how to do it?

Answer

The standard event dispatching can be used to fire a custom event on the Scene. A listener atached to the focusOwner property of the Scene can be used to trigger the event.

Example (java)

public class FocusEvent extends Event {

    public static final EventType FOCUS_EVENT_TYPE = new EventType(EventType.ROOT);

    public FocusEvent(Object source, EventTarget target) {
        super(source, target, FOCUS_EVENT_TYPE);
    }

}
@Override
public void start(Stage primaryStage) {
    TextArea ta1 = new TextArea();
    ta1.setId("ta1");
    TextArea ta2 = new TextArea();
    ta2.setId("ta2");
    VBox root = new VBox(ta1, ta2);
    root.addEventHandler(FocusEvent.FOCUS_EVENT_TYPE, evt -> {
        System.out.println("focused "+ evt.getTarget());
    });

    ta1.addEventHandler(FocusEvent.FOCUS_EVENT_TYPE, evt -> {
        System.out.println("You focused the first TextArea");
        evt.consume();
    });

    Scene scene = new Scene(root);
    scene.focusOwnerProperty().addListener((o, old, newValue) -> {
        if (newValue != null) {
            FocusEvent event = new FocusEvent(scene, newValue);
            Event.fireEvent(newValue, event);
        }
    });

    primaryStage.setScene(scene);
    primaryStage.show();
}