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

时间:2017-08-13 11:15:05

标签: scala model-view-controller fxml scalafx

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

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

Bellow我有两个控制器的代码

@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

1 个答案:

答案 0 :(得分:0)

我实际上是自己想出来的。该问题位于rootView内,通过创建新的FXMLView来接收该问题。为了访问正确的控制器,必须由加载器接收rootView,加载器已经用于获取控制器。

所以打电话

val rootView = loader.getRoot[jfxs.Parent]

而不是

val rootView = FXMLView(resource, NoDependencyResolver)

与上例中一样,rootView被传递给Scene构造函数。