简体   繁体   English

ScalaFX @sfxml 注释问题

[英]ScalaFX @sfxml Annotation Problems

I am writing a Scalafx application using FXML for the views with the scalafxml library.我正在使用 FXML 为带有 scalafxml 库的视图编写一个 Scalafx 应用程序。 I am having a ton of trouble getting the classes to compile when using the @sfxml annotation on controller classes.在控制器类上使用 @sfxml 注释时,我在编译类时遇到了很多麻烦。 When using them, I keep getting NoSuchMethodExceptions on my constructors as if I have no default constructor but this is definitely not the case.使用它们时,我的构造函数不断收到 NoSuchMethodExceptions,就好像我没有默认构造函数一样,但这绝对不是这种情况。 I have been studying this so much that I can only conclude that the problem must be with the library itself.我一直在研究这个,我只能得出结论,问题一定出在图书馆本身。 I have followed any information on it as best I know how.我已尽我所知跟踪了有关它的任何信息。

The controller is for creating a form for the user.控制器用于为用户创建表单。 Since the "IllegalArgumentException" will be thrown if I try to set the root node's scene twice, I use the root node's id in my constructor for purposes of avoiding the exception.由于如果我尝试两次设置根节点的场景将抛出“IllegalArgumentException”,我在构造函数中使用根节点的 id 以避免出现异常。

Any help is much appreciated.任何帮助深表感谢。 Thanks.谢谢。

My code:我的代码:

@sfxml
class ToolbarController(private val rootLayout: BorderPane) {

  val parent = calcParent

  import javafx.application.Platform
  def newForm = {
    new JFXPanel()
    Platform.runLater(new Runnable() {
      override def run() {

        val dialogStage = new Stage {
            scene = new Scene(parent) {
              stylesheets = List(getClass.getResource("/scala/css/form.css").toExternalForm)
            }
        }
        dialogStage.show()
        }
    })
  }


  def calcParent: Parent = {
    val resource = getClass.getResource("scala/form.fxml")
    if(rootLayout.scene == null)
      FXMLView(resource, NoDependencyResolver)
    else rootLayout.getParent
  }
}

The FXML: FXML:

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

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane id="rootLayout"maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="500.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="FormController">
   <center>...

And my stack trace:还有我的堆栈跟踪:

Exception in Application start method
Workaround until RT-13281 is implemented: keep toolkit alive
[error] (run-main-0) java.lang.RuntimeException: Exception in Application start method
java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$152(LauncherImpl.java:182)
    at com.sun.javafx.application.LauncherImpl$$Lambda$11/1268584418.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: javafx.fxml.LoadException: 
/Users/patrickslagle/scala/MyApps/PattyCakes/target/scala-2.11/classes/scala/calendar.fxml:7

    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2605)
    at javafx.fxml.FXMLLoader.access$700(FXMLLoader.java:104)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:928)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:967)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:216)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:740)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2711)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2531)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3218)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3128)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3108)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3101)
    at Calendar$.delayedEndpoint$Calendar$1(Calendar.scala:15)
    at Calendar$delayedInit$body.apply(Calendar.scala:9)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scalafx.application.JFXApp$$anonfun$init$1.apply(JFXApp.scala:297)
    at scalafx.application.JFXApp$$anonfun$init$1.apply(JFXApp.scala:297)
    at scala.collection.immutable.List.foreach(List.scala:383)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.collection.mutable.ListBuffer.foreach(ListBuffer.scala:45)
    at scalafx.application.JFXApp$class.init(JFXApp.scala:297)
    at Calendar$.init(Calendar.scala:9)
    at scalafx.application.AppHelper.start(AppHelper.scala:33)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
    at com.sun.javafx.application.LauncherImpl$$Lambda$62/2116169040.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl$$Lambda$58/1458556428.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
    at com.sun.javafx.application.PlatformImpl$$Lambda$60/778909025.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
    at com.sun.javafx.application.PlatformImpl$$Lambda$59/1397409682.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Caused by: java.lang.InstantiationException: controller.ToolbarController
    at java.lang.Class.newInstance(Class.java:427)
    at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:923)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:967)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:216)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:740)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2711)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2531)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3218)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3128)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3108)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3101)
    at Calendar$.delayedEndpoint$Calendar$1(Calendar.scala:15)
    at Calendar$delayedInit$body.apply(Calendar.scala:9)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scalafx.application.JFXApp$$anonfun$init$1.apply(JFXApp.scala:297)
    at scalafx.application.JFXApp$$anonfun$init$1.apply(JFXApp.scala:297)
    at scala.collection.immutable.List.foreach(List.scala:383)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.collection.mutable.ListBuffer.foreach(ListBuffer.scala:45)
    at scalafx.application.JFXApp$class.init(JFXApp.scala:297)
    at Calendar$.init(Calendar.scala:9)
    at scalafx.application.AppHelper.start(AppHelper.scala:33)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
    at com.sun.javafx.application.LauncherImpl$$Lambda$62/2116169040.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl$$Lambda$58/1458556428.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
    at com.sun.javafx.application.PlatformImpl$$Lambda$60/778909025.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
    at com.sun.javafx.application.PlatformImpl$$Lambda$59/1397409682.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Caused by: java.lang.NoSuchMethodException: controller.ToolbarController.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    at sun.reflect.misc.ReflectUtil.newInstance(ReflectUtil.java:51)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:923)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:967)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:216)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:740)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2711)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2531)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2445)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3218)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3179)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3152)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3128)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3108)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3101)
    at Calendar$.delayedEndpoint$Calendar$1(Calendar.scala:15)
    at Calendar$delayedInit$body.apply(Calendar.scala:9)
    at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
    at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
    at scalafx.application.JFXApp$$anonfun$init$1.apply(JFXApp.scala:297)
    at scalafx.application.JFXApp$$anonfun$init$1.apply(JFXApp.scala:297)
    at scala.collection.immutable.List.foreach(List.scala:383)
    at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
    at scala.collection.mutable.ListBuffer.foreach(ListBuffer.scala:45)
    at scalafx.application.JFXApp$class.init(JFXApp.scala:297)
    at Calendar$.init(Calendar.scala:9)
    at scalafx.application.AppHelper.start(AppHelper.scala:33)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$159(LauncherImpl.java:863)
    at com.sun.javafx.application.LauncherImpl$$Lambda$62/2116169040.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl$$Lambda$58/1458556428.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
    at com.sun.javafx.application.PlatformImpl$$Lambda$60/778909025.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
    at com.sun.javafx.application.PlatformImpl$$Lambda$59/1397409682.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
[trace] Stack trace suppressed: run last pattycakes/compile:run for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
    at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last pattycakes/compile:run for the full output.
[error] (pattycakes/compile:run) Nonzero exit code: 1
[error] Total time: 46 s, completed May 26, 2016 4:18:42 PM

You should not instantiate a class annotated with @fxml directly.你不应该直接实例化一个用@fxml注释的类。 This class is modified by the SFXML compiler macro.此类由 SFXML 编译器宏修改。 It is not shown in the code you posted but somewhere you must instantiate ToolbarController to call newForm .这是不是在您发布的代码所示,但地方必须实例ToolbarController调用newForm Posting Minimal, Complete, and Verifiable example is very important.发布最小、完整和可验证的示例非常重要。

Attempting to directly instantiate ToolbarController is the most likely cause of the NoSuchMethodExceptions as ToolbarController constructor is modified by the macro.尝试直接实例化ToolbarControllerNoSuchMethodExceptions的最可能原因,因为ToolbarController构造函数被宏修改。 You need to move methods newForm and calcParent outside of ToolbarController .你需要移动方法newFormcalcParent之外ToolbarController Only instantiate ToolbarController using FXMLView(resource, ...) .只有实例化ToolbarController使用FXMLView(resource, ...) You also need to add a reference to ToolbarController in the FXML file in the top pane:您还需要在顶部窗格的 FXML 文件中添加对ToolbarController的引用:

<BorderPane ... fx:controller="mypackage.ToolbarController"> ...

With that the FXMLView can instantiate ToolbarController using only reference to the FXML file.随着该FXMLView可以实例ToolbarController仅使用参考FXML文件。 For instance, the instantiation could look like this:例如,实例化可能如下所示:

import java.io.IOException
import scalafx.Includes._
import scalafx.application.JFXApp
import scalafx.application.JFXApp.PrimaryStage
import scalafx.scene.Scene
import scalafxml.core.{NoDependencyResolver, FXMLView}

object MyFXMLDemo extends JFXApp {

  val resource = getClass.getResource("/scala/css/form.css")
  if (resource == null) {
    throw new IOException("Cannot load resource: /scala/css/form.css")
  }

  val root = FXMLView(resource, NoDependencyResolver)

  stage = new PrimaryStage() {
    scene = new Scene(root)
  }

}

Please take look carefully at the example at https://github.com/vigoo/scalafxml-unit-converter-example .请仔细查看https://github.com/vigoo/scalafxml-unit-converter-example中的示例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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