Yeah, I thought about that, but it ended up being way more overhead. When I dug into it, bidirectional bindings are just implemented with change listeners on both properties, so it ended up being easier to just do
picker.valueProperty().addListener { _, _, new -> property.value = new?.convert }
property.addListener { _, _, new -> picker.value = new?,convert() }