Search code examples
kotlintornadofx

Tornadofx filterInput


I'd like to make a special format for a text field to convert to doubles. However, I want to use a comma for decimal separation instead of periods. I've been researching for days and have looked at the guide but I'm still having trouble. isDouble doesn't seem to work when using commas. Even if I used periods, the data is formatted wrong when being written back (i.e. textfield 12.13 becomes 1213.00 in the database). This is what I have so far:

val format = DecimalFormat("##0.00", DecimalFormatSymbols(Locale.GERMAN))

                        textfield(model.size, converter = object : StringConverter<Number>() {
                            override fun toString(number: Number?) = format.format(number)
                            override fun fromString(string: String?) = try {
                            format.parse(string).toDouble() } 
                            catch (e: ParseException) {0.0}
                        }){
                        filterInput {
                            val ba = mutableListOf<Boolean>().asObservable()
                            it.controlNewText.toCharArray().forEach { char ->
                                when {
                                    char.isDigit() -> ba.add(true)
                                    char == ',' -> ba.add(true)
                                    else -> ba.add(false)
                                }
                            }
                            when{
                                ba.any{false} -> return@filterInput false
                                else ->  return@filterInput true
                            } 
                        }}

Solution

  • Will this work? I know looping the old-school way and using variables (Gross!) isn't the coolest ways to handle things but the computation is relatively small and easy to understand.

    filterInput {
                    var decimalUsed = false
                    loop@ for (char in it.controlNewText) {
                        if (char == ',') {
                            if (decimalUsed) {
                                return@filterInput false
                            } else {
                                decimalUsed = true
                            }
                        } else if (!char.isDigit()) {
                            return@filterInput false
                        }
                    }
                    true
                }