Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin TornadFX如何使用子窗口模型列表创建MDI?_Kotlin_Tornadofx - Fatal编程技术网

Kotlin TornadFX如何使用子窗口模型列表创建MDI?

Kotlin TornadFX如何使用子窗口模型列表创建MDI?,kotlin,tornadofx,Kotlin,Tornadofx,我有以下几部分: class ChildModel:ViewModel() { //or it may be an POJO, it does not matter val value .... } class ParentView: View() { ... //Maybe this should be implemented into ParentViewModel val childrenList:List<ChildModel> f

我有以下几部分:

class ChildModel:ViewModel() { //or it may be an POJO, it does not matter
  val value ....      
} 

class ParentView: View() {
  ...
  //Maybe this should be implemented into ParentViewModel   
  val childrenList:List<ChildModel>

  fun addFragmentAsChild() {
    //should:
    // 1. display fragment within ParentView
    // 2. add fragment into modelList (or fragmentList - it does not matter -  important to have access to the model of every child )  
  }

  fun deleteFragmentAsChild() {
    //should destroy child and remove item from childrenList   
    //should work also on manual closing 
  }         
}

class ChildFragment: Fragment() {
  val model = ChildModel()      
...
}
class-ChildModel:ViewModel(){//或者它可能是一个POJO,这无关紧要
val值。。。。
} 
类ParentView:View(){
...
//也许这应该在ParentViewModel中实现
val儿童列表:列表
趣味addFragmentAsChild(){
//应:
//1.在ParentView中显示片段
//2.将片段添加到modelList(或fragmentList-这无关紧要-重要的是要访问每个孩子的模型)
}
有趣的deleteFragmentAsChild(){
//应销毁子项并从子项列表中删除项
//也应适用于手动关闭
}         
}
类ChildFragment:Fragment(){
val model=ChildModel()
...
}
小结:我想创建MDI,并为每个孩子访问模型

我尝试使用“openInternalWindow”帮助来实现这一点,但我不能创建多个子实例,我必须手动管理列表——这很糟糕

class InstrumentsView: View() {
  override val root = BorderPane()
  val instrumentList = ArrayList<InstrumentFragment>()

  init {
    with(root){
      top = menubar {
        menu("Tools") {
          menuitem("Add instrument", "Shortcut+A") {
            val newFragment = InstrumentFragment()
            instrumentList.add(newFragment)
            println(instrumentList.size)
            openInternalWindow(newFragment, modal = false)
          }

        }
      }
    }
  }
}
class InstrumentsView:View(){
覆盖val root=BorderPane()
val instrumentList=ArrayList()
初始化{
带(根){
顶部=菜单栏{
菜单(“工具”){
菜单项(“添加仪表”、“快捷方式+A”){
val newFragment=InstrumentFragment()
instrumentList.add(新片段)
println(instrumentList.size)
openInternalWindow(newFragment,modal=false)
}
}
}
}
}
}

如何正确操作?

在本例中,我将使用视图模型和范围来跟踪每个仪器编辑器的项目。我们需要确保这些工具是唯一的,这样我们就可以在编辑器关闭时将它们从列表中删除。我创建了一个带有id和名称的
仪器
域对象:

class Instrument {
    val idProperty = SimpleObjectProperty<UUID>(UUID.randomUUID())
    var id by idProperty

    val nameProperty = SimpleStringProperty()
    var name by nameProperty

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other?.javaClass != javaClass) return false

        other as Instrument

        if (id != other.id) return false

        return true
    }

    override fun hashCode(): Int {
        return id.hashCode()
    }
}
覆盖
InstrumentFragment
中的停靠回调以触发以下事件:

override fun onDock() {
    fire(InstrumentAdded(model.item))
}

override fun onUndock() {
    fire(InstrumentRemoved(model.item))
}
现在,我们将在主视图中保留仪器列表,
InstrumentsView
。这就像是在
控制器中一样

val instruments = FXCollections.observableArrayList<Instrument>()
不幸的是,我们不能使用
openInternalWindow
,因为它目前一次只支持一个内部窗口。因此,我改用了
openWindow

如果要从操作关闭编辑器,可以从片段内的任何位置调用
closeModal()

我已经包括了一个完整的示例应用程序,其中有一个TableView,显示了当前打开的仪器。它将如下图所示。请注意,在从模型中刷新更改并在表中可见之前,需要单击“保存”。

我希望这就是您想要的,或者您至少可以根据此示例修改它以适合您的用例

import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty
import javafx.collections.FXCollections
import tornadofx.*
import java.util.*

class Instrument {
    val idProperty = SimpleObjectProperty<UUID>(UUID.randomUUID())
    var id by idProperty

    val nameProperty = SimpleStringProperty()
    var name by nameProperty

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other?.javaClass != javaClass) return false

        other as Instrument

        if (id != other.id) return false

        return true
    }

    override fun hashCode(): Int {
        return id.hashCode()
    }
}

class InstrumentModel : ItemViewModel<Instrument>() {
    init {
        item = Instrument()
        item.name = "New instrument"
    }

    val name = bind { item?.nameProperty }
}

class InstrumentAdded(val instrument: Instrument) : FXEvent()
class InstrumentRemoved(val instrument: Instrument) : FXEvent()

class InstrumentFragment : Fragment("Instrument Editor") {
    val model: InstrumentModel by inject()

    override val root = form {
        prefWidth = 300.0
        fieldset("Edit instrument") {
            field("Name") {
                textfield(model.name)
            }
        }
        button("Save") {
            setOnAction {
                model.commit()
            }
        }
    }

    override fun onDock() {
        fire(InstrumentAdded(model.item))
    }

    override fun onUndock() {
        fire(InstrumentRemoved(model.item))
    }
}

class InstrumentsView : View() {
    val instruments = FXCollections.observableArrayList<Instrument>()

    override val root = borderpane {
        setPrefSize(400.0, 300.0)
        top {
            menubar {
                menu("Tools") {
                    menuitem("Add instrument", "Shortcut+A") {
                        find<InstrumentFragment>(Scope()).openWindow()
                    }
                }
            }
        }
        center {
            tableview(instruments) {
                column("Name", Instrument::nameProperty)
                columnResizePolicy = SmartResize.POLICY
            }
        }
    }

    init {
        subscribe<InstrumentAdded> {
            instruments.add(it.instrument)
        }
        subscribe<InstrumentRemoved> {
            instruments.remove(it.instrument)
        }
    }

}
导入javafx.beans.property.SimpleObject属性
导入javafx.beans.property.SimpleStringProperty
导入javafx.collections.FXCollections
导入tornadofx*
导入java.util*
类乐器{
val idProperty=SimpleObject属性(UUID.randomUUID())
按idProperty列出的变量id
val nameProperty=SimpleStringProperty()
按名称属性的变量名称
覆盖乐趣等于(其他:任何?):布尔值{
如果(this==other)返回true
if(other?.javaClass!=javaClass)返回false
作为工具的其他
如果(id!=other.id)返回false
返回真值
}
重写哈希代码():Int{
返回id.hashCode()
}
}
类InstrumentModel:ItemViewModel(){
初始化{
项目=仪器()
item.name=“新仪器”
}
val name=bind{item?.nameProperty}
}
添加了类InstrumentAdded(val instrument:instrument):FXEvent()
类InstrumentRemoved(val instrument:instrument):FXEvent()
类InstrumentFragment:Fragment(“仪器编辑器”){
val模型:InstrumentModel by inject()
覆盖val root=form{
预宽=300.0
字段集(“编辑仪器”){
字段(“名称”){
textfield(model.name)
}
}
按钮(“保存”){
坐骨作用{
model.commit()
}
}
}
覆盖fun onDock(){
火灾(添加仪表(型号项目))
}
覆盖onUndock()的乐趣{
火灾(拆除仪表(型号项目))
}
}
类InstrumentsView:View(){
val instruments=FXCollections.observableArrayList()
覆盖val root=borderpane{
setPrefSize(400.0、300.0)
顶{
梅努巴{
菜单(“工具”){
菜单项(“添加仪表”、“快捷方式+A”){
查找(Scope()).openWindow()
}
}
}
}
居中{
tableview(仪器){
列(“名称”,仪器::名称属性)
columnResizePolicy=SmartResize.POLICY
}
}
}
初始化{
订阅{
仪器.添加(it.仪器)
}
订阅{
仪器。移除(it。仪器)
}
}
}

在本例中,我将使用视图模型和范围来跟踪每个仪器编辑器的项目。我们需要确保这些工具是唯一的,这样我们就可以在编辑器关闭时将它们从列表中删除。我创建了一个带有id和名称的
仪器
域对象:

class Instrument {
    val idProperty = SimpleObjectProperty<UUID>(UUID.randomUUID())
    var id by idProperty

    val nameProperty = SimpleStringProperty()
    var name by nameProperty

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other?.javaClass != javaClass) return false

        other as Instrument

        if (id != other.id) return false

        return true
    }

    override fun hashCode(): Int {
        return id.hashCode()
    }
}
覆盖
InstrumentFragment
中的停靠回调以触发以下事件:

override fun onDock() {
    fire(InstrumentAdded(model.item))
}

override fun onUndock() {
    fire(InstrumentRemoved(model.item))
}
现在,我们将在主视图中保留仪器列表,
InstrumentsView
。这就像是在
控制器中一样

val instruments = FXCollections.observableArrayList<Instrument>()
不幸的是,我们不能使用
openInternalWindow
,因为它目前一次只支持一个内部窗口。因此,我改用了
openWindow

如果要从操作关闭编辑器,可以从片段内的任何位置调用
closeModal()

我已经包括了一个完整的示例应用程序,其中有一个TableView,显示了当前打开的I
import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty
import javafx.collections.FXCollections
import tornadofx.*
import java.util.*

class Instrument {
    val idProperty = SimpleObjectProperty<UUID>(UUID.randomUUID())
    var id by idProperty

    val nameProperty = SimpleStringProperty()
    var name by nameProperty

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other?.javaClass != javaClass) return false

        other as Instrument

        if (id != other.id) return false

        return true
    }

    override fun hashCode(): Int {
        return id.hashCode()
    }
}

class InstrumentModel : ItemViewModel<Instrument>() {
    init {
        item = Instrument()
        item.name = "New instrument"
    }

    val name = bind { item?.nameProperty }
}

class InstrumentAdded(val instrument: Instrument) : FXEvent()
class InstrumentRemoved(val instrument: Instrument) : FXEvent()

class InstrumentFragment : Fragment("Instrument Editor") {
    val model: InstrumentModel by inject()

    override val root = form {
        prefWidth = 300.0
        fieldset("Edit instrument") {
            field("Name") {
                textfield(model.name)
            }
        }
        button("Save") {
            setOnAction {
                model.commit()
            }
        }
    }

    override fun onDock() {
        fire(InstrumentAdded(model.item))
    }

    override fun onUndock() {
        fire(InstrumentRemoved(model.item))
    }
}

class InstrumentsView : View() {
    val instruments = FXCollections.observableArrayList<Instrument>()

    override val root = borderpane {
        setPrefSize(400.0, 300.0)
        top {
            menubar {
                menu("Tools") {
                    menuitem("Add instrument", "Shortcut+A") {
                        find<InstrumentFragment>(Scope()).openWindow()
                    }
                }
            }
        }
        center {
            tableview(instruments) {
                column("Name", Instrument::nameProperty)
                columnResizePolicy = SmartResize.POLICY
            }
        }
    }

    init {
        subscribe<InstrumentAdded> {
            instruments.add(it.instrument)
        }
        subscribe<InstrumentRemoved> {
            instruments.remove(it.instrument)
        }
    }

}