我在将JavaFX与Scala一起使用时遇到了一个非常奇怪的现象(我目前没有使用ScalaFX(。似乎我的控制器可以正确连接tableView
对象:
class MainController extends Initializable {
@FXML private var tableView: TableView[Trade] = null
然后我有以下初始化代码:
override def initialize(location: URL, resources: ResourceBundle): Unit = {
println(tableView)
正确打印
TableView[id=tableView, styleClass=table-view]
但是现在如果我添加以下代码:
override def initialize(location: URL, resources: ResourceBundle): Unit = {
println(tableView)
val refresher = new Timeline(new KeyFrame(Duration.seconds(5), new EventHandler[ActionEvent]() {
override def handle(event: ActionEvent) {
println("abc")
println(tableView)
}}))
}
然后,原始println()
将改为打印null
。 "abc"
永远不会被打印出来。这似乎是黑魔法。我已经能够始终如一地观察到这种行为。
有什么线索吗?它似乎以某种方式与闭包甚至 Scala 有关。我还没有在 Java 中尝试过类似的例子,但这似乎非常非常奇怪。
谢谢
经过大量挖掘和运行反编译器,我可以弄清楚问题是什么。
这个问题可能只会发生在Scala中。有一个简单的解决方法:始终将您的@FXML字段声明为公共字段,并且不会出现任何问题。
当字段是私有字段并且闭包需要访问此私有字段时,就会出现问题。因为对于一般情况,闭包无法访问该字段,因为它是私有的,因此编译器将代表您在类级别创建一个对象,并将您的字段放入其中。但是那个封闭对象将有一个奇怪的名称,因此Javafx的框架将无法为您正确填充此字段!