嵌套的自定义组件javafx-ClassNotFoundException

时间:2020-04-25 16:56:44

标签: java kotlin javafx

所以我知道已经有很多关于类似问题的帖子,但是这个帖子有些奇怪,因为我已经在这个问题上花费了5个小时,所以我将尽一切努力。

我要做的就是创建2个自定义组件,并将其中1个放在fxml文件中。它应该很简单,我之前使用其他类型的组件已经做到了,但是由于某种原因,现在它不喜欢它。看一下
SecondaryInterface.kt

import javafx.fxml.FXMLLoader
import javafx.scene.control.Label
import javafx.scene.layout.GridPane
import java.io.IOException

class SecondaryInterface : GridPane() {

    @FXML private lateinit var label: Label

    init {

        println("From SecondaryInterface: ")
        println("\t" + MainInterface::class.java)
        println("\t" + javaClass.getResource("main_interface.fxml"))
        println("\t" + javaClass.getResource("SecondaryInterface.kt"))
        println("\t" + javaClass.getResource("secondary_interface.fxml"))

        val fxmlLoader = FXMLLoader(javaClass.getResource("secondary_interface.fxml"))
        fxmlLoader.setRoot(this)
        fxmlLoader.setController(this)
        try {
            fxmlLoader.load<Any>()
        } catch (exception: IOException) {
            throw RuntimeException(exception)
        }
    }

}

secondary_interface.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<fx:root type="javafx.scene.layout.GridPane" xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml">

    <Label fx:id="label" text="This is the secondary interface"></Label>

</fx:root>

辅助接口是嵌套组件。没事吗?接下来,
MainInterface.kt

import javafx.fxml.FXML
import javafx.fxml.FXMLLoader
import javafx.scene.layout.GridPane
import java.io.IOException

class MainInterface : GridPane() {

    @FXML private lateinit var secondInterface: SecondaryInterface

    init {
        println("From MainInterface: ")
        println("\t" + MainInterface::class.java)
        println("\t" + javaClass.getResource("main_interface.fxml"))
        println("\t" + javaClass.getResource("SecondaryInterface.kt"))
        println("\t" + javaClass.getResource("secondary_interface.fxml"))

        val fxmlLoader = FXMLLoader(javaClass.getResource("main_interface.fxml"))
        fxmlLoader.setRoot(this)
        fxmlLoader.setController(this)
        try {
            fxmlLoader.load<Any>()
        } catch (exception: IOException) {
            throw RuntimeException(exception)
        }
    }
}

main_interface.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import SecondaryInterface?>

<fx:root type="javafx.scene.layout.GridPane"
         xmlns="http://javafx.com/javafx"
         xmlns:fx="http://javafx.com/fxml">

    <Label text="This is primary interface"></Label>
    <SecondaryInterface fx:id="secondInterface"></SecondaryInterface>

</fx:root>

输出/错误StackTrace

From MyApplication: 
    class MainInterface
    file:/E:/Programming/Tests/NestedCustomComponents/out/production/NestedCustomComponents/main_interface.fxml
    null
    file:/E:/Programming/Tests/NestedCustomComponents/out/production/NestedCustomComponents/secondary_interface.fxml
From MainInterface: 
    class MainInterface
    file:/E:/Programming/Tests/NestedCustomComponents/out/production/NestedCustomComponents/main_interface.fxml
    null
    file:/E:/Programming/Tests/NestedCustomComponents/out/production/NestedCustomComponents/secondary_interface.fxml
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: 
/E:/Programming/Tests/NestedCustomComponents/out/production/NestedCustomComponents/main_interface.fxml

    at MainInterface.<init>(MainInterface.kt:24)
    at MyApplication.start(MyApplication.kt:24)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    ... 1 more
Caused by: javafx.fxml.LoadException: 
/E:/Programming/Tests/NestedCustomComponents/out/production/NestedCustomComponents/main_interface.fxml

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2863)
    at javafx.fxml.FXMLLoader.processImport(FXMLLoader.java:2707)
    at javafx.fxml.FXMLLoader.processProcessingInstruction(FXMLLoader.java:2676)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2542)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
    at MainInterface.<init>(MainInterface.kt:22)
    ... 10 more
Caused by: java.lang.ClassNotFoundException
    at javafx.fxml.FXMLLoader.loadType(FXMLLoader.java:2914)
    at javafx.fxml.FXMLLoader.importClass(FXMLLoader.java:2861)
    ... 16 more

Process finished with exit code 1

我已经分析了太长时间,无法从中得到任何有用的信息-_-
到目前为止,这是我尝试过的:

  • 仔细检查命名约定(包名小写,类名以大写开头)
  • 多次重建项目
  • 确保我的进口货正确
  • 打印代码和输出中所见的调试文本(如类路径),以检查所需的文件是否引人注意(为什么找不到我的.kt文件,却可以找到我的.fxml文件?)
  • 在.fxml文件中指定fx:controller
  • 使用internal constructor()(在班级名称之后)
  • 将类声明为open
  • 添加VM参数
    --module-path
    C:\javafx-sdk-11.0.2\lib
    --add-modules
    javafx.controls,javafx.fxml

这是我正在做的一个更大的项目。我简化了所有内容以简化问题。
如果您想自己尝试一下,这是您需要的其他课程,

Main.kt

import javafx.application.Application

fun main(args: Array<String>) {
    Application.launch(MyApplication::class.java)
}

MyApplication.kt

import javafx.application.Application
import javafx.scene.Scene
import javafx.scene.layout.Pane
import javafx.stage.Stage
import MainInterface //Not imported because in same package

class MyApplication : Application() {

    fun main(args: Array<String>) { launch(*args) }

    override fun start(primaryStage: Stage) {

        val mainScene = Scene(Pane(), 475.0, 425.0)
        ScreenController.stage = primaryStage
        ScreenController.scene = mainScene
        ScreenController.bindSceneWithStage()

        println("From MyApplication: ")
        println("\t" + MainInterface::class.java)
        println("\t" + javaClass.getResource("main_interface.fxml"))
        println("\t" + javaClass.getResource("/SecondaryInterface.kt"))
        println("\t" + javaClass.getResource("secondary_interface.fxml"))

        ScreenController.addScene("mainInterface", MainInterface()) //Crashes here

        ScreenController.stage!!.show()
        ScreenController.activateScene("mainInterface")
    }
}

ScreenController.kt

import javafx.scene.Scene
import javafx.scene.layout.Pane
import javafx.stage.Stage
import java.util.*

object ScreenController {

    var stage: Stage? = null
    var scene: Scene? = null
    private val mapOfCustomPanes = mutableMapOf<String, Pane>()

    fun bindSceneWithStage() {
        stage!!.scene = scene!!
    }

    fun addScene(name: String, pane: Pane) {
        mapOfCustomPanes[name] = pane
    }

    fun removeScene(name: String?) {
        mapOfCustomPanes.remove(name)
    }

    fun activateScene(name: String?) {
        scene!!.root = mapOfCustomPanes[name]
    }
}

任何帮助将不胜感激,因为我对此一无所知。谢谢

0 个答案:

没有答案