Java 如何在TornadoFX中取消订阅活动?

Java 如何在TornadoFX中取消订阅活动?,java,events,kotlin,unsubscribe,tornadofx,Java,Events,Kotlin,Unsubscribe,Tornadofx,在TornadoFX中,我想取消订阅一个自定义事件,这样接收方就不会再处理不必要的事件,并可能避免类似内存泄漏的情况,但是,当我在代码中使用unsubscribe方法时,它根本不起作用。以下是我的代码部分: object MyEventObj: FXEvent(EventBus.RunOn.BackgroundThread) class MyEventBus(val personlist:List<PersonOld>): FXEvent() class MyController:

在TornadoFX中,我想取消订阅一个自定义事件,这样接收方就不会再处理不必要的事件,并可能避免类似内存泄漏的情况,但是,当我在代码中使用
unsubscribe
方法时,它根本不起作用。以下是我的代码部分:

object MyEventObj: FXEvent(EventBus.RunOn.BackgroundThread)
class MyEventBus(val personlist:List<PersonOld>): FXEvent()
class MyController: Controller()
{
    init
    {
        subscribe<MyEventObj> {
            unsubscribe<MyEventObj> { 
                println("Unsubscribe event!") //unsubscrib event and make sure the next code just runs once, but never works!
            }
            println("Event has received!")
            val items = listOf(PersonOld("Name A", 20), PersonOld("Name B", 25))
            fire(MyEventBus(items))
        }
    }
}
objectmyeventobj:FXEvent(EventBus.RunOn.BackgroundThread)
MyEventBus类(val personlist:List):FXEvent()
类MyController:Controller()
{
初始化
{
订阅{
取消订阅{
println(“Unsubscribe event!”)//取消订阅事件,并确保下一个代码只运行一次,但永远不会运行!
}
println(“事件已收到!”)
val项目=列表(个人姓名(“姓名A”,20),个人姓名(“姓名B”,25))
火灾(MyEventBus(项目))
}
}
}

那么,问题是什么?如何在TornadoFX中使用
取消订阅
?谢谢你提前帮助我

函数
unsubscribe
将事件侦听器作为其唯一参数。因此,为了能够取消订阅,您需要将侦听器保存为成员val,以便可以引用它。为了让事情变得更有趣,您不能在侦听器本身内部引用
,因此您需要调用另一个函数才能成功取消订阅。下面是一个完整的示例:

object MyEvent : FXEvent()

class MyView : View() {
    override val root = stackpane {
        paddingAll = 100
        button("Fire!") {
            setOnAction {
                fire(MyEvent)
            }
        }
    }

    val myListener: (MyEvent) -> Unit = {
        alert(Alert.AlertType.INFORMATION, "Event received!", "This message should only appear once.")
        stopListening()
    }

    init {
        subscribe(myListener)
    }

    fun stopListening() = unsubscribe(myListener)

}
如果可以从监听器内部引用监听器,我们可以直接在监听器内部添加一个
unsubscribe()
调用,但这是不可能的,至少在Kotlin 1.0中是不可能的

编辑:我们刚刚添加了一个
times=n
参数来订阅,所以您不需要自己处理注销。默认情况下,每次触发事件时都会触发事件侦听器,但通过传递
1
,您可以在第一次之后自动取消注册。使用TornadoFX 1.6.3中的这一新功能,您只需执行以下操作:

class MyView : View() {
    override val root = stackpane {
        paddingAll = 100
        button("Fire!") {
            setOnAction {
                fire(MyEvent)
            }
        }
    }

    init {
         subscribe<MyEvent>(times = 1) {
            alert(Alert.AlertType.INFORMATION, "Event received!", "This message should only appear once.")
        }
    }

}

这使得一些代码被添加和重写,最后我得到了它!谢谢,它已经在我的测试代码中起作用了。太好了:)你可能想在1.6.3发布后重新访问它,以进一步减少锅炉板:)太好了!!我迫不及待地检查新版本和新功能很快可用,最后我可以用我的方式使用它(∩_∩)
subscribe<MyEvent> {
    alert(Alert.AlertType.INFORMATION, "Event received!", "This message should only appear once.")
    unsubscribe()
}