1

JavaFX 场景的真正新手,所以就到这里。

格里芬 1.4.0 - jdk 1.7.0_45

griffon 插件 (groovyfx-0.9.1, javafx-0.10.0)

我正在尝试为我的一个文本字段实现一个简单的焦点侦听器。这个想法是,一旦文本字段被聚焦,我想在同一视图中更改标签的消息。我敢肯定答案很简单,但我认为我已经把复杂的事情搞砸了。

对于整体上下文,我试图通过读取 fxml 并使用 groovy 视图进行绑定等来实现我的视图。

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
}

查看 groovyfx 文档,似乎没有像 onAction 那样的 onFocus 方法,因此我必须向focusedProperty 添加一个侦听器 - 非常棒。我首先尝试为 ChangeListener 编写一个闭包:

aTextField.focusedProperty().addListener({ obsVal, oldVal, newVal ->
       // do something...    
})

但是 Uberbuilder 抱怨,我显然做错了(朝这个方向轻推会有所帮助)

所以我写了一个空的 FocusListener 类来实现一个 ChangeListener,然后在我的视图中绑定它。

class FocusListener implements ChangeListener<Boolean> {

@Override
public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldVal, Boolean newVal ) {
    // for the view to override...
}

}

那么在我看来

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'

                    }
                }
            }

        });

代码执行得很好(焦点获得打印)但当然我在范围内,所以我无权访问我的控制器或视图组件。为了咧嘴笑(不是真的喜欢它,而是尝试一下),我将控制器传递给了我的 FocusListener 的构造函数,并在我的控制器上调用了一个方法。

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...
}

}

然后在我看来

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
                    }
                }
            }

        });

没有任何抱怨,但我的控制器方法从未执行过(也没有任何抱怨,输出是“获得焦点”。在我的调试器中,我确实看到了对控制器的引用......但在这一点上,我陷入了兔子洞并且确信一个不正确的实现...

有人可以帮我吗?

谢谢!

4

1 回答 1

1

好的 - 所以经过更多的修补(并且运行良好)。这很容易。

在视图中,我向文本字段的focusedProperty 添加了一个侦听器。该侦听器在模型中被引用,因此:

aTextField.focusedProperty().addListener(model.fieldFocusListener)

然后在模型中我对已经绑定的值进行更改

@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')
        }
    }

}

这在模型中对我来说很有意义,因为我拥有操作视图所需的所有访问权限。无论如何,我希望这可以帮助其他有需要的人。

于 2013-11-18T23:40:31.223 回答