Scala - Obtenga FXML UI-Elements
Estoy trabajando en un proyecto Scala / JavaFX con IntelliJ y un complemento para scala.
La forma típica en Java para acceder a los elementos de su archivo fxml es establecer una identificación para cada elemento al que desea acceder y luego en su clase de controlador declarar una variable como "@FXML private Label mylabelid;".
En Scala funciona casi de la misma manera que puedes ver en mi código fuente. PERO obtengo una NullPointerException en la línea 73 (marcada con un PROBLEMA-comentario). Esta es la única etiqueta, que se establece en nulo. Intenté cosas diferentes. Cada elemento se está configurando como se espera, aparte de 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
}
}
Dime cuándo me perdí algo o si quieres saber algo más y gracias por tu ayuda.
Saludos Rastreador