java.lang.NoSuchMethodException 尝试 运行 TornadoFX 应用程序时

java.lang.NoSuchMethodException when trying to run TornadoFX Application

不确定是什么导致它在我的视图中找不到 "init" 函数,所以我想我 post 在这里看看是否有其他人有这个问题。

编译一切正常!然后当我 运行 我的程序时,我得到这个错误:

java.lang.InstantiationException: com.my.tfx.app.InputView
  at java.lang.Class.newInstance(Class.java:427)
  at tornadofx.FXKt.find(FX.kt:372)
  at tornadofx.FXKt.find$default(FX.kt:358)
  at tornadofx.App.start(App.kt:80)
  at com.my.tfx.app.UserInputUI.start(UserInputUI.kt:15)
  at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1(LauncherImpl.java:863)
  at com.sun.javafx.application.PlatformImpl.lambda$runAndWait(PlatformImpl.java:326)
  at com.sun.javafx.application.PlatformImpl.lambda$null(PlatformImpl.java:295)
  at java.security.AccessController.doPrivileged(Native Method)
  at com.sun.javafx.application.PlatformImpl.lambda$runLater(PlatformImpl.java:294)
  at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
  at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
  at com.sun.glass.ui.gtk.GtkApplication.lambda$null(GtkApplication.java:139)
  at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: com.my.tfx.app.InputView.<init>()
  at java.lang.Class.getConstructor0(Class.java:3082)
  at java.lang.Class.newInstance(Class.java:412)
  ... 13 more

不太确定是什么原因造成的。我有这样的设置:

class UserInputUI : App(InputView(SVGEnum.first, StringEnum.first, UserInput.validationFunctions)::class, UIStyles::class) {
  init {
    reloadStylesheetsOnFocus()
  }

  override fun start(stage: Stage) {
    super.start(stage)
    stage.minWidth = 1024.0
    stage.minHeight = 768.0
    stage.maxWidth = 2560.0
    stage.maxHeight = 1440.0
  }
}

class InputView(val s: SVGEnum, val q: StringEnum, val valFunArray : ArrayList<(String)-> Boolean>) : View() {

  override val root = stackpane {
    //contents ommitted cause they're super long and I dont think its relevant,
    //but I can add it in if requested
  }

}

有什么想法吗?或者这是一个错误?谢谢!

视图必须有一个无参数的构造函数,这样它们才能被框架实例化。在您的应用程序 subclass (UserInputUI) 中,您实际上实例化了 InputView youtrself 然后调用 ::class 来获取它的 KClass。您只应该直接将 KClass 传递给它,因此您需要修改代码,以便 UserInputUI 定义如下:

class UserInputUI : App(InputView::class, UIStyles::class)

(我省略了 init 块和启动覆盖。顺便说一下,确保你不在生产中调用 reloadStylesheetsOnFocus。为了确保它永远不会进入生产,删除它并设置TornadoFX IDEA 中的选项 运行 Configuration isstead).

接下来,您必须确保 InputView 具有 noargs 构造函数。您需要使用另一种技术将参数传递给它。由于您在应用 class 中对它们进行了硬编码,因此您也可以直接在 InputView 中对它们进行硬编码,或者您可以引入一个 ViewModel 并在 App.start 中基于命令行参数或配置文件(如果您愿意)。

简单地硬编码 InputView 中的值而不是 UserInputIU 中的值的重写看起来像这样:

class InputView() : View() {
    val s: SVGEnum = SVGEnum.first
    val q: StringEnum = StringEnum.first
    val valFunArray: ArrayList<(String) -> Boolean> = UserInput.validationFunctions

    override val root = stackpane {
    }
}

我希望这能澄清问题:)