2016-07-17 30 views
5

IntelliJ I'yi kullanmak bir JavaFX uygulaması oluşturdu ve Kotlin ve Maven'i çerçeveye ekledi. Bir sample.fxml dosyası ve bir Controller.java ve Main.java ile geldi. Kotlin'deki (MainWindowController.kt) denetleyici için yeni bir sınıf oluşturdum ve main.findml dosyasını MainWindow.fxml olarak yeniden adlandırdım. BenFXML denetimi daima Kotlin'i kullanırken boştur 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> 

Ve MainWindowController.kt dosyasında: Ben gibi görünmek MainWindow.fxml güncellenmiş

İşte
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}") 
    } 
} 

benim Main.java var:

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

koşuyorum Uygulamada, yazdırma satırı etiketin boş olduğunu gösterir, ancak aksi takdirde pencere düzgün bir şekilde gösterir ve metni etiketimden görürüm. Null sahip olduğum problem. Ben Kotlin ile FXML kullanarak fazla bir şey bulamadım ve bulduğum şey biraz eskidi ve gerçek bir çalışma çözümüne sahip gibi görünmüyordu.

Etiketin neden boş olduğunu bilen var mı? Yanlış bir şey yapmalıyım ya da bir şeyi yanlış anlamalıyım.

Düzenleme: İşte şimdi hızlı yanıtlar sayesinde çalıştığını ne var:

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

Ben KOTLIN bilmiyorum:

Kodunuz olabilir gibi görünüyor? –

+2

[TornadoFX] 'a göz atmalısınız (https://github.com/edvin/tornadofx). Kotlin'de JavaFX'i gerçekten güzel kılıyor ve hem düzen hem de stil için güvenli tipte DSL'lere sahip. –

+2

@ RuckusT-Boom'un yorumuna eklemek için, FXML'yi de destekler ve oldukça güzel bir şekilde düzenler. https://github.com/edvin/tornadofx-guide/blob/master/Part%202%20-%20Usage%20Basics/10.%20FXML.md – tmn

cevap

5

Sadece Java kurucular ile olduğu gibi, fx:id alanlar önce doldurulan ama olmayacak sonrainit (veya Java kurucu) denir.

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

Aslında 'Initializable' komutunu uygulamanıza gerek olmadığını unutmayın; sadece bir 'initialize()' metodunu tanımlamak yeterlidir. –

+0

Evet, başardı! Muhteşem. Geçersiz kılmadan daha kısa yol yaptım. – GregInWI2

+0

[JavaFX belgeleri] (https://docs.oracle.com/javafx/2/api/javafx/fxml/Initializable.html) uyarınca önerilen yol budur: NOT Bu arabirim, konumun otomatik enjeksiyonu ile yerini almıştır. ve denetleyiciye kaynak özellikleri. 'FXMLLoader', artık denetleyici tarafından tanımlanan herhangi bir uygun no-arg' initialize() 'yöntemini otomatik olarak arayacaktır. Enjeksiyon yaklaşımının mümkün olduğunda kullanılması tavsiye edilir. – Marv

6

Daha önce belirtildiği gibi: ortak bir çözüm Initializable arabirimini aleti (ya da sadece bir initialize() yöntemi tanımlar) ve bu gibi yöntemi içinde ek bir kurulum yapmaktır. Fx: id ayarlanmış olup olmadığını kontrol edin.

lateinit değiştiricisini kullanmak da mümkündür. Nesne inşaat parçası olarak adlandırılan `init` yöntemi geçerli:

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

class MainWindowController { 
    @FXML 
    lateinit var helloLabel : Label 
}