Scala - Get FXML UI-Elements

Deadly 提交于 2019-12-22 00:42:19

问题


I´m working on a Scala/JavaFX project with IntelliJ and a plugin for scala.
The typical way in Java to access elements of your fxml-file is to set an id for each element you want to access and then in your controllerclass declare a variable like "@FXML private Label mylabelid;".
In Scala it works almost the same way as you can see in my source code. BUT i get a NullPointerException in line 73 (marked with a PROBLEM-comment). This is the only label, which is just set to null. I tried diffrent things. Every single element is getting set as expected apart from 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
  }
}

Tell me when i missed something or you want to know something else and thank you for your help.
Greetings Tracker


回答1:


I found a workaround. When I declare missingInputLabel as public it works just fine. But actually I don´t want to declare it public because of "information hiding".



来源:https://stackoverflow.com/questions/31406700/scala-get-fxml-ui-elements

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!