使用Kotlin时,FXML控件始终为null

时间:2016-07-17 23:45:24

标签: java javafx fxml kotlin

使用IntelliJ我创建了一个JavaFX应用程序,然后将Kotlin和Maven作为框架添加到其中。它附带了一个sample.fxml文件以及一个Controller.java和Main.java。我在Kotlin(MainWindowController.kt)中为控制器创建了一个新类,并将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);
    }
}

当我运行应用程序时,打印行显示标签为空,否则窗口显示正确,我看到标签中的文本。 null是我遇到的问题。我在Kotlin上使用FXML并没有太多发现,我发现它有点过时,似乎没有实际的工作解决方案。

有谁知道标签为何为空?我必须做错事或误解。

编辑:由于快速回复,以下是我现有的工作:

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}")
    }
}

2 个答案:

答案 0 :(得分:11)

如前所述。检查是否设置了fx:id。

也可以使用lateinit修饰符。

您的代码可能如下所示:

import javafx.fxml.FXML
import javafx.scene.control.Label

class MainWindowController {
    @FXML 
    lateinit var helloLabel : Label
}

答案 1 :(得分:6)

就像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}")
    }
}