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