В этом примере я буду использовать модель представления и область видимости, чтобы отслеживать элемент для каждого редактора инструментов. Нам нужно убедиться, что инструменты уникальны, чтобы мы могли удалить их из списка при закрытии редактора. Я создал объект домена Instrument
с идентификатором и именем:
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()
}
}
Нам нужна модель представления, которую мы можем внедрить в редактор инструментов. Мы позаботимся о том, чтобы модель представления по умолчанию содержала новый инструмент. Он содержит фасад для свойства name, чтобы мы могли привязать его к полю ввода редактора.
class InstrumentModel: ItemViewModel<Instrument>() {
init {
item = Instrument()
item.name = "New instrument"
}
val name = bind { item?.nameProperty }
}
Fragment
имеет обратные вызовы для onDock
и onUndock
, которые можно использовать для отслеживания модели для этого фрагмента. Мы можем использовать события, чтобы сигнализировать об этом. Объявите следующие события:
class InstrumentAdded(val instrument: Instrument) : FXEvent()
class InstrumentRemoved(val instrument: Instrument) : FXEvent()
Переопределите обратные вызовы стыковки в InstrumentFragment
, чтобы инициировать эти события:
override fun onDock() {
fire(InstrumentAdded(model.item))
}
override fun onUndock() {
fire(InstrumentRemoved(model.item))
}
Пока мы сохраним список инструментов в главном окне InstrumentsView
. С таким же успехом это могло быть в Controller
.
val instruments = FXCollections.observableArrayList<Instrument>()
В классе init основного представления мы подпишемся на созданные нами события и изменим наш список:
subscribe<InstrumentAdded> {
instruments.add(it.instrument)
}
subscribe<InstrumentRemoved> {
instruments.remove(it.instrument)
}
Действие «New Instrument» откроет новый InstrumentEditor в новом Scope
, чтобы мы могли внедрить в него модель представления и получить экземпляр, уникальный для этого редактора.
menuitem("Add instrument", "Shortcut+A") {
find<InstrumentFragment>(Scope()).openWindow()
}
К сожалению, мы не можем использовать 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)
}
}
}
person
Edvin Syse
schedule
04.01.2017
this += InstrumentFragment
. - person Edvin Syse   schedule 04.01.2017