[Kotlin UI DSL] How to dynamically modify the options in comboBox at runtime?


I'm developing a tool with Kotlin UI DSL Version 1 and there are two combo boxes as shown in the picture

I want the effect that when the option in the green box is changed, the option in the blue box is dynamically replaced.

If I were developing this tool in swing, I could use the blue box's removeAllItems and addItem to do this when the green box's itemlistener event fires

But in the Kotlin UI DSL, I don't find any methods like addItem and removeAllItems, and there is no method to set the itemListener event - except for the button, I don't find any other component that has a method to set the event listener

I know about property binding, but... I change the options, and then use Messages to output the data values, but I find that the property values in data are always the default values... Even if I print the data after the dialog is closed, the properties are still the default values

val data = FrameData()
row {
comboBox(CollectionComboBoxModel(modules), data::module, SimpleListCellRenderer.create { label, value, _ ->
label.text = if (value is DummyModule) {
} else {
(value as Module).name
data class FrameData(
var language: Language = Language.UNKNOWN,
var module: Module = Constant.dummyModule,
var sourceRoot: VirtualFile = Constant.dummyFile

Many attempts at property binding were unsuccessful, I wanted to use a swing-like approach to do this, and also manually wrapped the component that can set the trigger event (below), but I got stuck on how to dynamically update the options inside the combo box ...

fun <T> Cell.radio(text: String, value: T, selected: (T) -> Unit): CellBuilder<JBRadioButton> {
val radio = JBRadioButton(text).apply {
addItemListener {
if (it.stateChange == ItemEvent.SELECTED) {
return radio()

fun <T> Cell.select(items: Array<T>, renderer: ListCellRenderer<T>, selected: (ItemEvent) -> Unit): CellBuilder<ComboBox<T>> {
val combo = ComboBox(items).apply {
this.renderer = renderer
addItemListener { selected(it) }
return combo()

So... How do I do this?



You can get the JComponent from the CellBuilder API, e.g.:

val myComboBox = comboBox(...)
val myComboBoxComponent = myComboBox.component
myComboBoxComponent.addItemListener { ... }

I have tried this way before, I can call addItem and removeAllItems methods, the ItemEvent of the two combo boxes did trigger, each Item triggered an event, but the ui did not change, the blue box still shows only a "---------- "
Is it necessary to redraw the ui? But after I call the repaint method, the ui is not refreshed, and the Items in the combo box are not replaced.


Could you please try with MutableCollectionComboBoxModel instead of CollectionComboBoxModel?


Yes, it worked! Thank you very much!


Please sign in to leave a comment.