Создать произвольный вид

Итак, у меня есть случай, когда мне нужно иметь N строк в виде: Label TextView/Checkbox. Возможно, мне понадобится больше этих двух представлений, поэтому я хочу иметь возможность поддерживать все, что есть TornadoFx View.

Я создал интерфейс с одним методом, который возвращает TornadoFx View, и он выглядит так:

interface ValueContainer {
    fun getView() : View
}

Одна из реализаций выглядит так:

class BooleanValueContainer(val checked: Boolean) : ValueContainer {

   val valueProperty = SimpleBooleanProperty(checked)

   override fun getView(): View {
       return (object : View() {
           override val root = checkbox {
               bind(valueProperty)
           }
       })
   }

}

Теперь, когда я пытаюсь использовать его внутри блока init, он не отображается в макете. root - это GridPane, а parameters - это список объектов, имеющих имя и ссылку на реализацию ValueContainer (BooleanValueContainer или другой, который я не показал):

init {
    with(root) {
        parameters.map {
            row(it.name) {
                it.parameterContainer.getView()
            }
        }
    }
}

Я застрял здесь довольно долго и пробовал все, что мог найти, но ничего не работало, кроме помещения блока textview или checkbox вместо вызова getView(), но тогда мне нужно было бы иметь логику в том, какое представление я должен отображать внутри этого класса который представляет собой представление, а я этого не хочу.


person Sven Vidak    schedule 29.10.2016    source источник


Ответы (1)


Причина, по которой это не работает для вас, заключается в том, что вы просто вызываете parameterContainer.getView(), но не добавляете View в строку. Я думаю, что вас сбивает с толку то, что для строителей вы можете просто сказать, например, label(), и он будет добавлен к текущему узлу в дереве построителя. В вашем случае вы просто говорите Label() (просто создайте экземпляр Label, а не вызывайте конструктор меток), который создаст новый Label, но не добавит его в список дочерних элементов текущего узла. Чтобы решить вашу проблему, сделайте:

this += it.parameterContainer.getView()

Это добавит вид в строку.

Кроме того, я не совсем понимаю смысл ValueContainer. Что решает установка представления в этот контейнерный объект? Я подозреваю, что это тоже может быть из-за недоразумения, и я хотел бы понять, почему вы считаете, что вам нужна эта конструкция.

person Edvin Syse    schedule 29.10.2016
comment
Потому что мне нужно показывать разные представления для разных типов данных. Например. если тип данных является логическим, мне нужен флажок, если это строка или число, мне нужно текстовое поле, если это массив параметров, мне нужен счетчик / поле со списком (не уверен в названии) - person Sven Vidak; 30.10.2016
comment
Я бы посоветовал изучить компонент формы. Переберите свои параметры, проверьте тип и добавьте нужный редактор поля. Похоже, что View per parameter - это излишне. - person Edvin Syse; 01.11.2016