将带有构造函数参数的视图添加到边界窗格

时间:2019-06-17 22:01:32

标签: javafx kotlin tornadofx

我想将相同的类添加到具有不同构造函数参数(一个为true,另一个为false)的不同BorderPane上,但是似乎UIComponents不能具有任何参数,但是却没有使该页面崩溃

添加参数intelliJ告诉我它正在尝试进行比较?? 我曾尝试将视图添加为VBox,但随后什么也没有出现,我也尝试过使用AnchorPane而不是BorderPane,但也没有显示任何内容。

更新:

class ZoomedOutView : View("ZoomedOutView") { 
    val audioView = find<AudioView>(mapOf(AudioView::playFromFile to false)) 
    //TODO change views to fragments 
    override val root = borderpane {
        bottom = audioLiveView.root
    }
}

查看需要参数的类:

class AudioView(var playFromFile: Boolean) : View("AudioView"){ 
    //constructor() : this(playFromFile) //error: cannot access because superclass constructor has been called        
    var audioSensor = AudioSensor()    
    override val root = vbox(10) { 
        vbox { 
            prefWidth = 1600.0 hbox { 
                if (!playFromFile) {
                    dataCollectionToggle = togglebutton {
                    ...
                    audioSensor.captureaudio()
... ...
}

编译错误如下(它需要一个初始化方法,在该方法中,可以对布尔值进行硬编码,但这不是我想要的逻辑):

Caused by: java.lang.InstantiationException: view.AudioLiveView
    at java.lang.Class.newInstance(Class.java:427)
    at tornadofx.FXKt.find(FX.kt:408)
    at app.ExpertView.<init>(a5_ExpertView.kt:51)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at java.lang.Class.newInstance(Class.java:442)
    at tornadofx.FXKt.find(FX.kt:408)
    at tornadofx.FXKt.find$default(FX.kt:393)
    at tornadofx.UIComponent.replaceWith(Component.kt:899)
    at tornadofx.UIComponent.replaceWith$default(Component.kt:898)
    at app.MenuView$root$1$1$1$5$1.invoke(MenuView.kt:94)
    at app.MenuView$root$1$1$1$5$1.invoke(MenuView.kt:14)
    at tornadofx.ControlsKt$action$4.handle(Controls.kt:515)
    at tornadofx.ControlsKt$action$4.handle(Controls.kt)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.control.MenuItem.fire(MenuItem.java:462)
    at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.doSelect(ContextMenuContent.java:1405)
    at com.sun.javafx.scene.control.skin.ContextMenuContent$MenuItemContainer.lambda$createChildren$343(ContextMenuContent.java:1358)
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
    at javafx.event.Event.fireEvent(Event.java:198)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    ... 9 more
Caused by: java.lang.NoSuchMethodException: view.AudioLiveView.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.newInstance(Class.java:412)
    ... 57 more

1 个答案:

答案 0 :(得分:0)

绝对不要手动实例化视图或片段。但是,您可以将find与特殊参数一起使用,该特殊参数包括应传递给View或Fragment的参数。请记住,一个View在当前作用域中只会被实例化一次,因此,如果您需要打开多个使用相同参数初始化的相同类型的UIComponent,请确保它们是Fragments。

有关更多信息,请参见指南的“组件”部分:

https://github.com/edvin/tornadofx-guide/blob/master/part1/3.%20Components.md

在上面的文档中搜索“将参数传递给视图”。

也就是说,使用范围将信息传递给视图几乎总是更好的选择。您可以在指南中详细了解这些最佳做法。

请注意,您不能将构造函数参数添加到ui组件中,因为框架需要一个无参数的构造函数才能实例化该类。使用by param扩展名传递参数,如下所示:

class AudioView : Fragment("AudioView") {
    val playFromFile: Boolean by param()

    override val root = vbox {
    }
}

还要注意,要在同一范围内获取多个实例,您需要使用Fragment而不是View,因为View是范围内的单例。