由于未在控制器中设置字段,使用 ScalaFX 在两个阶段之间传递信息失败

Passing information between two stages with ScalaFX fails due to not setting the field in controller

我正在尝试了解 ScalaFX 与 ScalaFXML 相结合的消息传递可能性。我创建了一个小例子,它有两个视图,控制器在 FXML 中定义。第一个(或Main)视图应该通过按下按钮将字符串发送到第二个(或Dialog)视图。

我按照 ScalaFXML Github page 的示例并使用特征来获取控制器,我可以调用 Dialog 控制器上的方法,该方法将字段设置为不同的值。此方法被正确调用,但当我通过单击按钮进行检查时,该字段未被覆盖。这是否与 ScalaFXML 注入控制器有关?

下面我有两个控制器的代码

@sfxml
class MainController(val clicky: Button,
                     val inputText: TextField,
                     val resultText: TextArea) {

  /** Creates a new window (in addition to the main window) and passes the contents of the text view to this window */
  def onButtonPressed(): Unit = {

    // Create the new window
    val dialogFXML: String = "/Dialog.fxml"
    val resource = getClass.getResource(dialogFXML)
    val rootView = FXMLView(resource, NoDependencyResolver)

    val loader = new FXMLLoader(resource, NoDependencyResolver)
    loader.load()
    val controller = loader.getController[AmountReceiver]
    controller.setAmount(inputText.text.value)

    val dialog = new Stage() {
      title = "Add Person"
      scene = new Scene(rootView)
      resizable = false
      initModality(Modality.ApplicationModal)
    }

    if (!dialog.showing()) {
      dialog.show()
    } else {
      dialog.requestFocus()
    }
  }
}

@sfxml
class DialogController(val minAmountOfWords: Label,
                       val sendToMainButton: Button,
                       val input: TextArea) extends AmountReceiver {

  var amount: String = "empty"

  def submitText(): Unit = {
    println(s"The actual amount is ${this.amount}")

    // Close Dialog
    quitDialog()
  }

  override def setAmount(amount: String): Unit = {
    this.amount = amount
    println(s"Setting the amount to ${this.amount}")
  }


  def quitDialog(): Unit = {
    val stage: Stage = input.getScene.getWindow.asInstanceOf[Stage]
    stage.close()
  }

}

运行 此代码并在文本字段中输入“2”,将打印以下输出:

Setting the amount to 2
The actual amount is empty

其实我自己想出来了。问题在于 rootView,它是通过创建一个新的 FXMLView 接收的。为了访问正确的控制器,加载程序必须接收 rootView,它已经用于获取控制器。

所以打电话

val rootView = loader.getRoot[jfxs.Parent]

而不是

val rootView = FXMLView(resource, NoDependencyResolver)

就像上面的例子一样,rootView 被传递给场景构造函数。