Dynamically replacing dialog input components using the DSL UI
Answered
I have a text input field whose type (plain text vs file path) depends on the value of a combo box field. When the user changes the combo box field, I would like to the text input field to be modified immediately:
I am using the Kotlin DSL UI. I am using the onChange
handler on the comboBox
component, but I have tried several approaches and cannot figure out how to replace the textField
component from there.
This is the relevant method of the AnsibleSettingsConfigurable
class (see mdklatt/idea-ansible-plugin). What needs to happen in comboBox.onChanged()
to replace the adjacent textField
component?
/**
* Create the UI component for defining settings.
*/
override fun Panel.createContent() {
row {
comboBox(installTypeOptions.values).let {
it.bindItem(
getter = { installTypeOptions[installType] },
setter = { installType = installTypeOptions.findFirstKey(it)!! }
)
it.onChanged {
// Various attempts to implement this have failed, such as
// reassigning the value of locationField (see below),
// calling createContent() on the parent component, and
// removing locationField before createLocationField() is
// called.
// Update the location input field to reflect the new
// install type. Cannot use `installType` property here
// because changes have not been applied yet.
// TODO: Would that it were this simple, but it is not.
//val newInstallType = installTypeOptions.findFirstKey(it.selectedItem)!!
//locationField = createLocationField(newInstallType)
}
}
// This should be a dynamic field based on the install type, but
// attempts to update this dynamically when installType changes
// have not been successful (see above). For now, use the least
// common denominator, a plain text field.
// TODO: createLocationField(this, installType)
textField().bindText(::ansibleLocation)
}
row("Config file:") {
textFieldWithBrowseButton(
"Ansible Config File",
fileChooserDescriptor = FileChooserDescriptorFactory.createSingleFileDescriptor(),
).bindText(::configFile)
}
}
Please sign in to leave a comment.
Hi Michael,
I suggest creating two components and using
visibleIf(comboBox.component.selectedValueMatches {…})
.A similar approach is used here: https://github.com/JetBrains/intellij-community/blob/241/plugins/coverage/src/com/intellij/coverage/JavaCoverageOptions.kt
This works well, thank you.