El control FXML siempre es nulo cuando se usa Kotlin
Usando IntelliJ, creé una aplicación JavaFX y luego agregué Kotlin y Maven como frameworks. Viene con un file sample.fxml y un Controller.java y Main.java. Creé una nueva class para el controller en Kotlin (MainWindowController.kt) y cambié el nombre del file sample.fxml a MainWindow.fxml. Actualicé MainWindow.fxml para que se vea así:
<?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>
Y en mi file MainWindowController.kt tengo:
- "Convertir" Clase de vista a anotación android
- ¿Cómo encontrar methods con una anotación en una class?
- Kotlin con Eclipse y JRebel
- ViewPager en Fragment no está funcionando por segunda vez
- La aplicación de enum consiste en 3 adaptadores entre 2 actividades en Kotlin
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}") } }
Aquí está mi 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); } }
Cuando ejecuto la aplicación, la línea de printing muestra que la label es nula, pero de lo contrario la window se muestra correctamente y veo el text de mi label. El nulo es el problema que estoy teniendo. No he encontrado mucho sobre el uso de FXML con Kotlin y lo que encontré estaba un poco desactualizado y no parecía tener una solución de trabajo real.
¿Alguien sabe por qué la label es nula? Debo estar haciendo algo mal o mal entendiendo algo.
Editar: Esto es lo que tengo que ahora funciona gracias a las respuestas rápidas:
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}") } }
- ¿Por qué no puedo configurar oyente en Kotlin?
- La habilitación de la security del método global Spring Security interrumpe la dependency injection (con Kotlin)
- Kotlin / Java, matriz de cadenas aún no inicializada en la llamada al método
- Tener problemas para escribir en EditText en Kotlin
- Spring & kotlin: ¿Cuál es la diferencia entre el constructor y la inyección tardía?
- ¿Cómo declarar variables en Android (Kotlin) usando el estilo del código de Google?
- no se puede convertir en org.jetbrains.kotlin.java.model.types.JeClassInitializerExecutableTypeMirror
- Location.distanceTo devuelve valor en metros pero necesito pies
Al igual que con los constructores de Java, los campos fx:id
no se rellenarán antes, pero después de que se init
el init
(o en Java, el constructor). Una solución común es implementar la interfaz de Initializable
(o simplemente definir un método de initialize()
) y realizar una configuration adicional dentro del método de esta manera:
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}") } }
Como se mencionó antes. Compruebe si fx: id está configurado.
También es posible usar el modificador lateinit
.
Tu código podría verse así:
import javafx.fxml.FXML import javafx.scene.control.Label class MainWindowController { @FXML lateinit var helloLabel : Label }
- Falló la inferencia del tipo de Kotlin: no coincide el tipo "matriz encontrada <*?>, Matriz obligatoria <*>?"
- Usar subrayado ("_") justo después de una variable en templates de cadena en Kotlin