Как сделать двустороннее связывание строк, чтобы текстовое поле можно было редактировать? - PullRequest
0 голосов
/ 04 ноября 2019

У меня есть сложный объект, который я хочу отобразить в текстовом поле. Это работает нормально с stringBinding. Но я не знаю, как сделать его двусторонним, чтобы текстовое поле можно было редактировать.

package com.example.demo.view

import javafx.beans.property.SimpleObjectProperty
import javafx.beans.property.SimpleStringProperty
import tornadofx.*

class MainView : View("Hello TornadoFX") {
    val complexThing: Int = 1
    val complexProperty = SimpleObjectProperty<Int>(complexThing)

    val complexString = complexProperty.stringBinding { complexProperty.toString() }

    val plainString = "asdf"
    val plainProperty = SimpleStringProperty(plainString)

    override val root = vbox {
        textfield(complexString)
        label(plainProperty)
        textfield(plainProperty)
    }
}

Когда я запускаю это, plainString редактируется, и я вижу изменение метки, потому что редактированиевозвращаясь к свойству.

Как я могу написать собственный обработчик или какой класс мне нужно использовать, чтобы заставить stringBinding быть прочитанным и write? Я просмотрел много документации по недвижимости и связующей документации, но не увидел ничего очевидного.

Ответы [ 2 ]

0 голосов
/ 06 ноября 2019

Та-Да

class Point(val x: Int, val y: Int) //You can put properties in constructor

class PointConverter: StringConverter<Point?>() {
    override fun fromString(string: String?): Point? {
        if(string.isNullOrBlank()) return null //Empty strings aren't valid
        val xy = string.split(",", limit = 2) //Only using 2 coordinate values so max is 2
        if(xy.size < 2) return null //Min values is also 2
        val x = xy[0].trim().toIntOrNull() //Trim white space, try to convert
        val y = xy[1].trim().toIntOrNull()
        return if(x == null || y == null) null //If either conversion fails, count as invalid
        else Point(x, y)
    }

    override fun toString(point: Point?): String {
        return "${point?.x},${point?.y}"
    }
}

class MainView : View("Hello TornadoFX") {
    val point = Point(5, 6) //Probably doesn't need to be its own member
    val pointProperty = SimpleObjectProperty<Point>(point)
    val pc = PointConverter()

    override val root = vbox {
        label(pointProperty, converter = pc) //Avoid extra properties, put converter in construction
        textfield(pointProperty, pc)
    }
}

Я внес изменения в ваш конвертер в «учётную запись» для неверного ввода, просто вернув ноль. Это просто простое решение, которое не обеспечивает корректный ввод, но отказывается вводить неверные значения в ваше свойство.

0 голосов
/ 05 ноября 2019

Вероятно, это можно сделать более чисто. Бьюсь об заклад, есть способ обойтись без дополнительной собственности. Пример хрупок, потому что он не выполняет проверку ввода в интересах простоты. Но это работает, чтобы продемонстрировать решение:

class Point(x: Int, y: Int) {
    val x: Int = x
    val y: Int = y
}

class PointConverter: StringConverter<Point?>() {
    override fun fromString(string: String?): Point? {
        val xy = string?.split(",")
        return Point(xy[0].toInt(), xy[1].toInt())
    }

    override fun toString(point: Point?): String {
        return "${point?.x},${point?.y}"
    }
}

class MainView : View("Hello TornadoFX") {
    val point = Point(5, 6)
    val pointProperty = SimpleObjectProperty<Point>(point)
    val pointDisplayProperty = SimpleStringProperty()
    val pointStringProperty = SimpleStringProperty()
    val pc = PointConverter()

    init {
        pointDisplayProperty.set(pc.toString(pointProperty.value))
        pointStringProperty.set(pc.toString(pointProperty.value))
        pointStringProperty.addListener { observable, oldValue, newValue ->
            pointProperty.set(pc.fromString(newValue))
            pointDisplayProperty.set(pc.toString(pointProperty.value))
        }
    }

    override val root = vbox {
        label(pointDisplayProperty)
        textfield(pointStringProperty)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...