使用 Kotlin 时 FXML 控件始终为 null
FXML control always null when using Kotlin
我使用 IntelliJ 创建了一个 JavaFX 应用程序,然后将 Kotlin 和 Maven 作为框架添加到其中。它带有一个 sample.fxml 文件和一个 Controller.java 和 Main.java。我在 Kotlin (MainWindowController.kt) 中为控制器创建了一个新的 class,并将 sample.fxml 文件重命名为 MainWindow.fxml。我将 MainWindow.fxml 更新为:
<?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>
在我的 MainWindowController.kt 文件中我有:
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}")
}
}
这是我的 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);
}
}
当我 运行 应用程序时,打印行显示标签为空,否则 window 正确显示并且我看到标签中的文本。 null 是我遇到的问题。我没有找到太多关于将 FXML 与 Kotlin 结合使用的信息,而且我发现的内容有点过时并且似乎没有实际可行的解决方案。
有谁知道为什么标签为空?我一定是做错了什么或者误解了什么。
编辑:由于快速回复,这是我现在可以使用的内容:
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}")
}
}
就像 Java 构造函数一样,fx:id
字段不会在 之后 init
之前填充(或在 Java 构造函数) 被调用。一个常见的解决方案是实现 Initializable
接口(或者只定义一个 initialize()
方法)并在方法内部进行额外的设置,如下所示:
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}")
}
}
如前所述。检查是否设置了fx:id。
也可以使用lateinit
修饰符。
您的代码可能如下所示:
import javafx.fxml.FXML
import javafx.scene.control.Label
class MainWindowController {
@FXML
lateinit var helloLabel : Label
}
我使用 IntelliJ 创建了一个 JavaFX 应用程序,然后将 Kotlin 和 Maven 作为框架添加到其中。它带有一个 sample.fxml 文件和一个 Controller.java 和 Main.java。我在 Kotlin (MainWindowController.kt) 中为控制器创建了一个新的 class,并将 sample.fxml 文件重命名为 MainWindow.fxml。我将 MainWindow.fxml 更新为:
<?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>
在我的 MainWindowController.kt 文件中我有:
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}")
}
}
这是我的 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);
}
}
当我 运行 应用程序时,打印行显示标签为空,否则 window 正确显示并且我看到标签中的文本。 null 是我遇到的问题。我没有找到太多关于将 FXML 与 Kotlin 结合使用的信息,而且我发现的内容有点过时并且似乎没有实际可行的解决方案。
有谁知道为什么标签为空?我一定是做错了什么或者误解了什么。
编辑:由于快速回复,这是我现在可以使用的内容:
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}")
}
}
就像 Java 构造函数一样,fx:id
字段不会在 之后 init
之前填充(或在 Java 构造函数) 被调用。一个常见的解决方案是实现 Initializable
接口(或者只定义一个 initialize()
方法)并在方法内部进行额外的设置,如下所示:
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}")
}
}
如前所述。检查是否设置了fx:id。
也可以使用lateinit
修饰符。
您的代码可能如下所示:
import javafx.fxml.FXML
import javafx.scene.control.Label
class MainWindowController {
@FXML
lateinit var helloLabel : Label
}