@@ -14,16 +14,15 @@ import com.intellij.ui.components.JBTextField
1414import com.intellij.ui.dsl.builder.Align
1515import com.intellij.ui.dsl.builder.bindText
1616import com.intellij.ui.dsl.builder.panel
17+ import com.intellij.ui.dsl.builder.whenItemChangedFromUi
1718import com.intellij.util.ui.UIUtil
1819import com.mitteloupe.cag.cleanarchitecturegenerator.form.OnChangeDocumentListener
1920import com.mitteloupe.cag.cleanarchitecturegenerator.form.PredicateDocumentFilter
2021import com.mitteloupe.cag.cleanarchitecturegenerator.validation.SymbolValidator
21- import java.awt.event.FocusAdapter
22- import java.awt.event.FocusEvent
22+ import java.awt.EventQueue.invokeLater
2323import java.io.File
2424import javax.swing.DefaultComboBoxModel
25- import javax.swing.JComponent
26- import javax.swing.SwingUtilities
25+ import javax.swing.JTextField
2726import javax.swing.text.AbstractDocument
2827
2928private const val USE_CASE_SUFFIX = " UseCase"
@@ -36,26 +35,28 @@ class CreateUseCaseDialog(
3635) : DialogWrapper(project) {
3736 private val useCaseNameTextField = JBTextField ()
3837 private val directoryField = TextFieldWithBrowseButton ()
39- private val inputDataTypeComboBox = ComboBox <String >()
38+ private lateinit var inputDataTypeComboBox: ComboBox <String >
4039 private val inputWarningLabel = JBLabel ()
41- private val outputDataTypeComboBox = ComboBox <String >()
40+ private lateinit var outputDataTypeComboBox: ComboBox <String >
4241 private val outputWarningLabel = JBLabel ()
4342 private val modelClassFinder = ModelClassFinder ()
4443 private val symbolValidator = SymbolValidator ()
45-
46- private var documentListenersSetup = false
44+ private val inputDataTypeModel = DefaultComboBoxModel < String >()
45+ private val outputDataTypeModel = DefaultComboBoxModel < String >()
4746
4847 val useCaseNameWithSuffix: String
4948 get() = useCaseName.removeSuffix(USE_CASE_SUFFIX ) + USE_CASE_SUFFIX
5049
5150 private val useCaseName: String
5251 get() = useCaseNameTextField.text.trim()
5352
53+ private var _inputDataType : String? = null
5454 val inputDataType: String?
55- get() = (inputDataTypeComboBox.selectedItem as ? String )?.trim()?. takeIf { it.isNotEmpty() }
55+ get() = _inputDataType
5656
57+ private var _outputDataType : String? = null
5758 val outputDataType: String?
58- get() = (outputDataTypeComboBox.selectedItem as ? String )?.trim()?. takeIf { it.isNotEmpty() }
59+ get() = _outputDataType
5960
6061 val destinationDirectory: File ?
6162 get() = directoryField.text.trim().takeIf { it.isNotEmpty() }?.let { File (it) }
@@ -86,17 +87,17 @@ class CreateUseCaseDialog(
8687 setupWarningLabels()
8788 }
8889
89- override fun getPreferredFocusedComponent (): JComponent = useCaseNameTextField
90+ override fun getPreferredFocusedComponent () = useCaseNameTextField
9091
9192 override fun show () {
9293 super .show()
9394
94- SwingUtilities . invokeLater {
95+ invokeLater {
9596 validateFieldOnChange()
9697 }
9798 }
9899
99- override fun createCenterPanel (): JComponent =
100+ override fun createCenterPanel () =
100101 panel {
101102 row(CleanArchitectureGeneratorBundle .message(" dialog.usecase.name.label" )) {
102103 textField()
@@ -108,11 +109,34 @@ class CreateUseCaseDialog(
108109 )
109110 }
110111 row(CleanArchitectureGeneratorBundle .message(" dialog.usecase.input.type.label" )) {
111- cell(inputDataTypeComboBox)
112+ @Suppress(" UnstableApiUsage" )
113+ comboBox(inputDataTypeModel)
114+ .whenItemChangedFromUi { _inputDataType = it }
115+ .applyToComponent {
116+ isEditable = true
117+ (editor.editorComponent as JTextField ).validateOnChange {
118+ _inputDataType = text
119+ }
120+ selectedItem = DEFAULT_DATA_TYPE
121+ inputDataTypeComboBox = this
122+ }
112123 cell(inputWarningLabel)
113124 }
114125 row(CleanArchitectureGeneratorBundle .message(" dialog.usecase.output.type.label" )) {
115- cell(outputDataTypeComboBox)
126+ @Suppress(" UnstableApiUsage" )
127+ comboBox(outputDataTypeModel)
128+ .whenItemChangedFromUi { _outputDataType = it }
129+ .applyToComponent {
130+ isEditable = true
131+ (editor.editorComponent as JTextField ).validateOnChange {
132+ _inputDataType = text
133+ }
134+ addActionListener {
135+ validateFieldOnChange()
136+ }
137+ selectedItem = DEFAULT_DATA_TYPE
138+ outputDataTypeComboBox = this
139+ }
116140 cell(outputWarningLabel)
117141 }
118142 row(CleanArchitectureGeneratorBundle .message(" dialog.usecase.directory.field.label" )) {
@@ -137,22 +161,6 @@ class CreateUseCaseDialog(
137161 outputWarningLabel.clearWarning()
138162 }
139163
140- private fun setupDocumentListenersIfNeeded () {
141- if (documentListenersSetup) {
142- return
143- }
144-
145- val inputEditor = inputDataTypeComboBox.editor.editorComponent as ? JBTextField
146- val outputEditor = outputDataTypeComboBox.editor.editorComponent as ? JBTextField
147-
148- if (inputEditor != null && outputEditor != null ) {
149- inputEditor.validateOnChange()
150- outputEditor.validateOnChange()
151-
152- documentListenersSetup = true
153- }
154- }
155-
156164 private fun validateFieldOnChange () {
157165 inputDataType.validateDataType(inputWarningLabel)
158166 outputDataType.validateDataType(outputWarningLabel)
@@ -228,33 +236,17 @@ class CreateUseCaseDialog(
228236 val modelClasses = modelClassFinder.findModelClasses(destinationDirectory)
229237 val allOptions = ModelClassFinder .PRIMITIVE_TYPES + modelClasses
230238
231- inputDataTypeComboBox.enableAndPopulateComboBox(allOptions)
232- outputDataTypeComboBox.enableAndPopulateComboBox(allOptions)
233- }
234- }
235-
236- private fun <T > ComboBox<T>.enableAndPopulateComboBox (options : List <T >) {
237- isEditable = true
238- addActionListener {
239- validateFieldOnChange()
239+ inputDataTypeModel.addAll(allOptions)
240+ outputDataTypeModel.addAll(allOptions)
240241 }
241- model = DefaultComboBoxModel <T >().apply { addAll(options) }
242- selectedItem = DEFAULT_DATA_TYPE
243242 }
244243
245- private fun JBTextField.validateOnChange () {
246- document.addDocumentListener(OnChangeDocumentListener { validateFieldOnChange() })
247- addFocusListener(
248- object : FocusAdapter () {
249- override fun focusGained (event : FocusEvent ) {
250- setupDocumentListenersIfNeeded()
251- }
252-
253- override fun focusLost (event : FocusEvent ) {
254- validateFieldOnChange()
255- }
244+ private fun JTextField.validateOnChange (onChange : JTextField .() -> Unit ) {
245+ document.addDocumentListener(
246+ OnChangeDocumentListener {
247+ onChange()
248+ validateFieldOnChange()
256249 }
257250 )
258- addActionListener { validateFieldOnChange() }
259251 }
260252}
0 commit comments