将带有构造函数参数的视图添加到边框

Adding view with constructor arguments to a borderpane

我想将相同的 class 添加到具有不同构造函数参数(一个为真,另一个为假)的不同 BorderPane,但似乎 UIComponents 还不能有参数 none 页面崩溃

添加参数后,intelliJ 显示它正在尝试进行比较?? 我尝试将视图添加为 VBox´s,但随后什么也没有出现,我也尝试了 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 需要参数:

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()
... ...
}

编译错误如下(它想要一个硬编码布尔值的init方法,但不是我想要的逻辑):

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.invoke(MenuView.kt:94)
    at app.MenuView$root.invoke(MenuView.kt:14)
    at tornadofx.ControlsKt$action.handle(Controls.kt:515)
    at tornadofx.ControlsKt$action.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$createChildren3(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.access00(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

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

有关详细信息,请参阅 guide 的组件部分:

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

在上面的文档中搜索 "Passing Parameters to Views"。

也就是说,使用范围将信息传递给视图几乎总是更好。您可以在 guide.

中阅读有关这些最佳实践的更多信息

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

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

    override val root = vbox {
    }
}

另请注意,为了能够在同一范围内获取多个实例,您需要使用片段,而不是视图,因为视图是范围内的单例。