简体   繁体   中英

Can't infer proper type myself in Kotlin when using JavaFX

I just started to study Kotlin and JavaFX by following tutorial. I could see blank JavaFX windows, and I proceed next step that using FXML.

import javafx.application.Application
import javafx.fxml.FXMLLoader
import javafx.scene.Scene
import javafx.stage.Stage

class AppMain : Application() {

    override fun start(primaryStage: Stage) {
        primaryStage.title = "Try JavaFX"
        val fxml = javaClass.getResource("fxml/Main.fxml")
        val root = FXMLLoader.load(fxml) // ERRORS here! `load`
        val scene = Scene(root)

        primaryStage.scene = scene

        primaryStage.show()
    }

}

However, I couldn't figure out that how to avoid the type inferencing error like:
Error:(12, 31) Kotlin: Type inference failed: Not enough information to infer parameter T in fun <T : Any!> load(p0: URL!): T! Please specify it explicitly.

From the message, I understand that I have to write the type of variable fxml explicitly. But I have no idea that what type should be labeled to fxml .

I tried to read the document about JavaFX, but I couldn't figure it out.(I'm not familiar with Java and Kotlin) I tried to type like URL but it does not make sense.

Many JavaFX & Kotlin example codes that I could find from google does not seems to have the problem like this. (Are the example codes written in previous version?) What type should I put for the variable? Or did I miss something other?

Environment and Codes

Environment

  • JDK 11
  • JavaFX 11
  • Kotlin 1.2.71

My complete trial code

https://github.com/QuietJoon/StudyKotlin-JavaFX/tree/fxml

The problem isn't the parameter to the FXMLLoader.load function (which is a java.net.URL object, as returned by javaClass.getResource ). It's that this function returns a generic type:

public static <T> T load(URL location)

The Kotlin compiler needs to know what type your root variable will be (as you've not explicitly defined it), but it can't know that as there's nothing in the code that will allow it to infer this.

A quick Google returned this example which has this code in it (in Java):

Parent root = FXMLLoader.load(getClass().getResource("fxml_example.fxml"));

As you can see here, the root variable is of type Parent . So what you need to do is provide this type (ie what you expect the load function to return) in some way. Here are two different ways you could do this:

  1. Specify the type explicitly when declaring the variable: val root: Parent = FXMLLoader.load(fxml)
  2. Specify the generic type when calling the method: val root = FXMLLoader.load<Parent>(fxml)

Note also that in your build.gradle file in your github repo there's a mistake that means the code didn't immediately compile when I fetched it:

compile "org.openjfx.javafx.fxml:11:$platform" should be compile "org.openjfx:javafx-fxml:11:$platform" (one of the dots should be a colon).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM