Scala - получить элементы пользовательского интерфейса FXML

Я работаю над проектом Scala / JavaFX с IntelliJ и плагином для Scala.
Типичный способ в Java для доступа к элементам вашего fxml-файла состоит в том, чтобы установить идентификатор для каждого элемента, к которому вы хотите получить доступ, а затем в вашем классе контроллеров объявить переменную, такую ​​как "@FXML private Label mylabelid;".
В Scala это работает почти так же, как вы можете видеть в моем исходном коде. НО я получаю исключение NullPointerException в строке 73 (помечено комментарием ПРОБЛЕМА). Это единственная метка, для которой просто установлено значение null. Я пробовал разные вещи. Каждый отдельный элемент устанавливается должным образом, кроме missingInputLabel.
LoginView.fxml:

<?xml version="1.0" encoding="UTF-8"?>
<?import java.net.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<GridPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="logingui.LoginController">
    <stylesheets>
        <URL value="@/data/gtevStyle.css" />
    </stylesheets>

    <Label text="SSH-Nutzername:" GridPane.columnIndex="0" GridPane.rowIndex="0" />
    <TextField fx:id="sshNameField" promptText="SSH-Nutzername" onKeyReleased="#onKeyReleased_textField" GridPane.columnIndex="1" GridPane.rowIndex="0" />
    <Label text="SSH-Passwort:" GridPane.columnIndex="0" GridPane.rowIndex="1" />
    <PasswordField fx:id="sshPasswdField" promptText="SSH-Passwort" onKeyReleased="#onKeyReleased_textField" GridPane.columnIndex="1" GridPane.rowIndex="1" />
    <Label text="Datenbank-Nutzername:" GridPane.columnIndex="0" GridPane.rowIndex="2" />
    <TextField fx:id="databaseNameField" promptText="Datenbank-Nutzername" onKeyReleased="#onKeyReleased_textField" GridPane.columnIndex="1" GridPane.rowIndex="2" />
    <Label text="Datenbank-Passwort:" GridPane.columnIndex="0" GridPane.rowIndex="3" />
    <PasswordField fx:id="databasePasswdField" promptText="Datenbank-Passwort" onKeyReleased="#onKeyReleased_textField" GridPane.columnIndex="1" GridPane.rowIndex="3" />

    <Label text="Name oder Passwort falsch" fx:id="nameOrPasswdWrong" styleClass="warningLabel" GridPane.columnIndex="1" GridPane.rowIndex="4" />
    <Label text="Fehlende Angaben" fx:id="missingInputLabel" styleClass="warningLabel" GridPane.columnIndex="1" GridPane.rowIndex="5" />
    <Button text="Login" onAction="#login" GridPane.columnIndex="0" GridPane.rowIndex="5" />
</GridPane>

LoginController.scala:

package logingui

import java.net.URL
import java.sql.SQLException
import java.util.ResourceBundle
import java.util.logging.Level
import java.util.logging.Logger
import javafx.fxml.FXML
import javafx.fxml.Initializable
import javafx.scene.control.Label
import javafx.scene.control.PasswordField
import javafx.scene.control.TextField
import javafx.scene.input.KeyEvent
import javafx.scene.input.KeyCode
import connection.GTEVConnection
import javafx.stage.Stage

class LoginController extends Initializable {
  @FXML
  private var nameOrPasswdWrong: Label = _
  @FXML
  private var missingInputLabel: Label = _ //TODO missingInputLabel is set to null?!
  @FXML
  private var sshNameField: TextField = _
  @FXML
  private var databaseNameField: TextField = _
  @FXML
  private var sshPasswdField: PasswordField = _
  @FXML
  private var databasePasswdField: PasswordField = _
  //Um einfach auf alle Text-/Passwortfelder referenzieren zu können
  private var textFields: Array[TextField] = Array[TextField](sshNameField, databaseNameField, sshPasswdField, databasePasswdField)
  var callbackWhenFinished: () => Unit = () => GTEVConnection.close() //Default: Simply close GTEVConnection

  def onKeyReleased_textField(ev: KeyEvent) { //TODO declare def as private and mark with @FXML?
    if (ev.getCode == KeyCode.ENTER) {
      login()
    } else {
      nameOrPasswdWrong.setVisible(false)
    }
  }

  def login() {
    checkInputOfTextFields()
    try {
      if (!missingInputLabel.isVisible) {
        GTEVConnection.createConnection(sshNameField.getText, sshPasswdField.getText, databaseNameField.getText, databasePasswdField.getText)
        callbackWhenFinished()
        sshNameField.getScene.getWindow.asInstanceOf[Stage].close()
      }
    } catch {
      case ex: SQLException =>
        Logger.getLogger("LoginContollerLogger").log(Level.SEVERE, null, ex) //TODO Loggername durch Klassennamen ersetzen
        nameOrPasswdWrong.setVisible(true)
    }
  }

  private def checkInputOfTextFields() {
    var anyMissingInput: Boolean = false
    for (t: TextField <- textFields) {
      if (t.getText.isEmpty) {
        anyMissingInput = true
        t.getStyleClass.add("missingInput")
      } else {
        t.getStyleClass.remove("missingInput")
      }
      missingInputLabel.setVisible(anyMissingInput)
    }
  }

  override def initialize(location: URL, resources: ResourceBundle) {
    nameOrPasswdWrong.setVisible(false)
    missingInputLabel.setVisible(false) //PROBLEM: NullPointerException
  }
}

Скажите мне, когда я что-то пропустил, или вы хотите узнать что-то еще, и спасибо за вашу помощь.
Приветствие Трекер

Ответы на вопрос(1)

Ваш ответ на вопрос