Managing FXML Always Matters When Using Kotlin

Using IntelliJ, I created a JavaFX application, and then added Kotlin and Maven as frameworks to it. It comes with a file sample.fxml and Controller.java and Main.java. I created a new class for the controller in Kotlin (MainWindowController.kt) and renamed the sample.fxml file to MainWindow.fxml. I updated MainWindow.fxml to look like this:

<?import javafx.scene.control.Label?> <?import javafx.scene.layout.GridPane?> <GridPane fx:controller="reader.MainWindowController" xmlns:fx="http://javafx.com/fxml" xmlns="http://javafx.com/javafx/8" alignment="center" hgap="10" vgap="10"> <Label fx:id="helloLabel" text="Hello"/> </GridPane> 

And in my MainWindowController.kt file I have:

 package reader import javafx.fxml.FXML import javafx.scene.control.Label class MainWindowController { @FXML var helloLabel: Label? = null init { println("Label is null? ${helloLabel == null}") } } 

Here is my Main.java:

 import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception{ Parent root = FXMLLoader.load(getClass().getClassLoader().getResource("MainWindow.fxml")); primaryStage.setTitle("My App"); primaryStage.setScene(new Scene(root, 1000, 600)); primaryStage.show(); } public static void main(String[] args) { launch(args); } } 

When I launch the application, the print line shows that the label is NULL, but otherwise the window displays correctly and I see the text from my label. Zero is the problem I am facing. I don't know much about using FXML with Kotlin, and what I found was a bit dated and didn't seem to have a real working solution.

Does anyone know why the label is zero? I have to do something wrong or misunderstand something.

Edit: this is what I now get thanks to quick answers:

 package reader import javafx.fxml.FXML import javafx.scene.control.Label class MainWindowController { @FXML var helloLabel: Label? = null fun initialize() { println("Label is null? ${helloLabel == null}") } } 
+7
source share
2 answers

As in the case of Java constructors, the fx:id fields will not be filled before, but after init is called (or in the Java constructor). A common solution is to implement the Initializable interface (or simply define the initialize() method) and additional configuration inside the method:

 import javafx.fxml.FXML import javafx.scene.control.Label class MainWindowController : Initializable { @FXML var helloLabel: Label? = null override fun initialize(location: URL?, resources: ResourceBundle?) { println("Label is null? ${helloLabel == null}") } } 
+6
source

As mentioned earlier. Check if fx: id is set.

You can also use the lateinit modifier.

Your code might look like this:

 import javafx.fxml.FXML import javafx.scene.control.Label class MainWindowController { @FXML lateinit var helloLabel : Label } 
+13
source

All Articles