2016-07-17 8 views
5

IntelliJの使用JavaFXアプリケーションを作成し、フレームワークとしてKotlinとMavenを追加しました。これには、sample.fxmlファイルとController.javaとMain.javaが付属しています。私はKotlin(MainWindowController.kt)のコントローラー用の新しいクラスを作成し、sample.fxmlファイルの名前をMainWindow.fxmlに変更しました。私が見えるようにMainWindow.fxmlを更新:FXMLコントロールは常にKotlinを使用するとnullです

<?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であることを印刷行に示します。そうでなければ、ウィンドウが正しく表示され、ラベルからテキストが表示されます。 nullは私が持っている問題です。私はKotlinでFXMLを使用することにそれほど気づきませんでした。私が見つけたのは、時代遅れで、実際の作業の解決策を持っていないようでした。

ラベルがnullである理由を知っている人はいますか?私は間違ったことや何かを誤解しているに違いない。

編集:ここで私は今、迅速な回答のおかげで動作することを持っているものだ:

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

私はKotlinを知らない:オブジェクト構築の一環として呼び出さ 'init'方法ですか? –

+2

[TornadoFX](https://github.com/edvin/tornadofx)をチェックしてください。それはKotlinのJavaFXを本当にいいものにし、レイアウトとスタイルの両方に対してタイプセーフなDSLを持っています。 –

+2

@ RuckusT-Boomさんのコメントに追加するには、FXMLもサポートしていて、非常にうまく合理化しています。 https://github.com/edvin/tornadofx-guide/blob/master/Part%202%20-%20Usage%20Basics/10.%20FXML.md – tmn

答えて

5

ただ、Javaのコンストラクタと同様、fx:idフィールドは前に埋めたがされることはありませんinit(または中のJavaコンストラクタ)が呼び出されます。前に述べたように

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

実際には 'Initializable'を実装する必要はありません。単純に 'initialize()'メソッドを定義するだけで十分です。 –

+0

うん、それはそれをやった!驚くばかり。私はそれを上書きなしでもっと短くした。 – GregInWI2

+0

[JavaFXのドキュメント](https://docs.oracle.com/javafx/2/api/javafx/fxml/Initializable.html)と同様の推奨方法です:注記このインタフェースは、場所の自動挿入に取って代わりましたリソースプロパティをコントローラに追加します。 'FXMLLoader'はコントローラによって定義された適切にアノテートされた引数なしの' initialize() 'メソッドを自動的に呼び出します。可能であれば注入手法を使用することをお勧めします。 – Marv

6

:一般的な解決策はInitializableインタフェースを実装する(または単にinitialize()方法を定義する)等のようなメソッド内の追加の設定を行うことです。 fx:idが設定されているか確認してください。

修飾子lateinitも使用できます。

あなたのコードでしたが、次のようになります。

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

class MainWindowController { 
    @FXML 
    lateinit var helloLabel : Label 
} 
関連する問題