将带有构造函数参数的视图添加到borderpane [英] Adding view with constructor arguments to a borderpane

查看:110
本文介绍了将带有构造函数参数的视图添加到borderpane的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to add a the same class to different BorderPane´s with different constructor arguments (one true and the other false) but it seems UIComponents cannot have arguments yet giving none crashes the page

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

Adding the parameter, intelliJ shows me it is attempting to make a comparison?? I have tried adding the Views as VBox´s instead, but then nothing appears, I have also tried an AnchorPane instead of BorderPane but that displays nothing as well.

更新:

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

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

The compile error is as follows (it wants an init method in which hardcoding a Boolean value works but isn't the logic I want):

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

推荐答案

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

You should absolutely never manually instantiate a View or Fragment. You can however use find with a special argument that includes the parameters that should be passed to the View or Fragment. Keep in mind that a View will only be instantiated once in the current scope, so if you need to open several UIComponents of the same type, initialized with different parameters, make sure they are Fragments.

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

See the Components section of the guide for more information:

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

在上面的文档中搜索将参数传递给视图".

Search for "Passing Parameters to Views" in the document above.

也就是说,使用范围将信息传递给视图几乎总是更好的选择.您可以在指南中阅读有关这些最佳做法的更多信息.

That said, it's almost always better to use scopes to pass information to views. You can read more about these best practices in the guide.

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

Note that you cannot add constructor parameters to your ui components, since the framework needs a no args constructor to be able to instantiate the class. Parameters are passed using the by param extension, like this:

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

    override val root = vbox {
    }
}

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

Also note that to be able to get multiple instances in the same scope you need to use Fragment, not View, since Views are singletons within a scope.

这篇关于将带有构造函数参数的视图添加到borderpane的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆