diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/CheckboxComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/CheckboxComponent.kt new file mode 100644 index 00000000000..01a3f1a0f22 --- /dev/null +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/CheckboxComponent.kt @@ -0,0 +1,32 @@ +package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components + +import com.intellij.ui.components.JBCheckBox +import com.intellij.ui.components.JBTextField +import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext +import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingValidator +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.textField + +class CheckboxComponent( + valuesReadingContext: ValuesReadingContext, + labelText: String? = null, + initialValue: Boolean? = null, + validator: SettingValidator? = null, + onValueUpdate: (Boolean) -> Unit = {} +) : UIComponent( + valuesReadingContext, + labelText, + validator, + onValueUpdate +) { + override val uiComponent: JBCheckBox = JBCheckBox(labelText, initialValue ?: false).apply { + addChangeListener { + fireValueUpdated(this@apply.isSelected) + } + } + + override fun updateUiValue(newValue: Boolean) = safeUpdateUi { + uiComponent.isSelected = newValue + } + + override fun getUiValue(): Boolean = uiComponent.isSelected +} \ No newline at end of file diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/DropDownComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/DropDownComponent.kt index 3d5ef3cb328..6e73b8999c6 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/DropDownComponent.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/DropDownComponent.kt @@ -3,46 +3,34 @@ package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components import com.intellij.openapi.ui.ComboBox import com.intellij.ui.ColoredListCellRenderer import com.intellij.ui.SimpleTextAttributes +import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingValidator import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult -import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext import org.jetbrains.kotlin.tools.projectWizard.core.entity.settingValidator -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.Component -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel -import java.awt.BorderLayout -import javax.swing.JComponent import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator import org.jetbrains.kotlin.utils.addToStdlib.safeAs import java.awt.event.ItemEvent -import javax.swing.DefaultComboBoxModel import javax.swing.Icon import javax.swing.JList class DropDownComponent( private val valuesReadingContext: ValuesReadingContext, - private val initialValues: List = emptyList(), + initialValues: List = emptyList(), labelText: String? = null, - private val filter: (T) -> Boolean = { true }, + filter: (T) -> Boolean = { true }, private val validator: SettingValidator = settingValidator { ValidationResult.OK }, private val iconProvider: (T) -> Icon? = { null }, - private val onAnyValueUpdate: (T) -> Unit = {} -) : Component() { + onValueUpdate: (T) -> Unit = {} +) : UIComponent( + valuesReadingContext, + labelText, + validator, + onValueUpdate +) { @Suppress("UNCHECKED_CAST") - - private val validationIndicator = ValidationIndicator(defaultText = labelText, showText = true) - - private var allowFireEventWhenValueUpdated: Boolean = true - - private fun withoutActionFiring(action: () -> Unit) { - val initialAllowFireEventWhenValueUpdated = allowFireEventWhenValueUpdated - allowFireEventWhenValueUpdated = false - action() - allowFireEventWhenValueUpdated = initialAllowFireEventWhenValueUpdated - } - - @Suppress("UNCHECKED_CAST") - private val comboBox = ComboBox().apply { + override val uiComponent: ComboBox = ComboBox( + initialValues.filter(filter).toTypedArray() as Array + ).apply { renderer = object : ColoredListCellRenderer() { override fun customizeCellRenderer( list: JList, @@ -69,55 +57,19 @@ class DropDownComponent( } } - addItemListener { e -> - if (e?.stateChange == ItemEvent.SELECTED) { - value = e.item as T + addItemListener { event -> + if (event?.stateChange == ItemEvent.SELECTED) { + @Suppress("UNCHECKED_CAST") + (event.item as? T)?.let(::fireValueUpdated) } } } - override fun onInit() { - super.onInit() - updateValues(initialValues) - } - - fun updateValues(newValues: List) { - val newValuesFiltered = newValues.filter(filter) - val oldValue = comboBox.selectedItem - withoutActionFiring { - @Suppress("UNCHECKED_CAST") - comboBox.model = DefaultComboBoxModel(newValuesFiltered.toTypedArray() as Array) - } - - if (oldValue !in newValuesFiltered) { - newValuesFiltered.firstOrNull()?.let { newValue -> - value = newValuesFiltered.first() - } - } - } - - override val component: JComponent = panel { - add(validationIndicator, BorderLayout.NORTH) - add(comboBox, BorderLayout.CENTER) + override fun updateUiValue(newValue: T) = safeUpdateUi { + uiComponent.selectedItem = newValue } @Suppress("UNCHECKED_CAST") - var value: T - get() = comboBox.selectedItem as T - set(value) { - comboBox.selectedItem = value - fireValueChanged(value) - } - - private fun fireValueChanged(newValue: T) { - validate(newValue) - if (allowFireEventWhenValueUpdated) { - onAnyValueUpdate(newValue) - } - } - - fun validate(value: T = this.value) { - validationIndicator.validationState = validator.validate(valuesReadingContext, value) - } + override fun getUiValue(): T = uiComponent.selectedItem as T } diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/PathFieldComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/PathFieldComponent.kt index 9f0ed99c39d..b29e4e67447 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/PathFieldComponent.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/PathFieldComponent.kt @@ -6,24 +6,32 @@ import com.intellij.openapi.ui.TextFieldWithBrowseButton import org.jetbrains.kotlin.tools.projectWizard.core.entity.StringValidator import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext +import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingValidator +import org.jetbrains.kotlin.tools.projectWizard.core.entity.settingValidator import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.Component import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.textField import java.awt.BorderLayout +import java.nio.file.Path +import java.nio.file.Paths +import javax.swing.Icon import javax.swing.JComponent class PathFieldComponent( - private val valuesReadingContext: ValuesReadingContext, - private val initialText: String = "", - labelText: String? = "", - private val validator: StringValidator = org.jetbrains.kotlin.tools.projectWizard.core.entity.settingValidator { ValidationResult.OK }, - private val onSuccessValueUpdate: (String) -> Unit = {}, - private val onAnyValueUpdate: (String) -> Unit = {} -) : Component() { - private val validationIndicator = ValidationIndicator(defaultText = labelText, showText = true) - private val pathField = TextFieldWithBrowseButton( - textField(initialText, this::fireValueChanged) + valuesReadingContext: ValuesReadingContext, + labelText: String? = null, + initialValue: Path? = null, + validator: SettingValidator? = null, + onValueUpdate: (Path) -> Unit = {} +) : UIComponent( + valuesReadingContext, + labelText, + validator, + onValueUpdate +) { + override val uiComponent: TextFieldWithBrowseButton = TextFieldWithBrowseButton( + textField(initialValue?.toString().orEmpty()) { path -> fireValueUpdated(Paths.get(path)) } ).apply { addBrowseFolderListener( TextBrowseFolderListener( @@ -33,33 +41,9 @@ class PathFieldComponent( ) } - override val component: JComponent = panel { - add(validationIndicator, BorderLayout.NORTH) - add(pathField, BorderLayout.CENTER) + override fun updateUiValue(newValue: Path)= safeUpdateUi { + uiComponent.text = newValue.toString() } - - var value: String - get() = pathField.text - set(value) { - pathField.text = value - fireValueChanged(value) - } - - private fun fireValueChanged(text: String) { - validate(text) - if (validationIndicator.validationState == ValidationResult.OK) { - onSuccessValueUpdate(text) - } - onAnyValueUpdate(text) - } - - override fun onInit() { - super.onInit() - validate(initialText) - } - - private fun validate(text: String) { - validationIndicator.validationState = validator.validate(valuesReadingContext, text) - } + override fun getUiValue(): Path = Paths.get(uiComponent.text) } \ No newline at end of file diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/TextFieldComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/TextFieldComponent.kt index b06a8df6520..07a47d66ad0 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/TextFieldComponent.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/TextFieldComponent.kt @@ -1,54 +1,27 @@ package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components -import org.jetbrains.kotlin.tools.projectWizard.core.entity.StringValidator -import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult +import com.intellij.ui.components.JBTextField import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext -import org.jetbrains.kotlin.tools.projectWizard.core.entity.settingValidator -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.Component -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator +import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingValidator import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.textField -import java.awt.BorderLayout -import javax.swing.JComponent class TextFieldComponent( - private val valuesReadingContext: ValuesReadingContext, - private val initialText: String = "", - labelText: String? = "", - private val validator: StringValidator = settingValidator { ValidationResult.OK }, - private val onSuccessValueUpdate: (String) -> Unit = {}, - private val onAnyValueUpdate: (String) -> Unit = {} -) : Component() { - private val validationIndicator = ValidationIndicator(defaultText = labelText, showText = true) - private val textField = textField(initialText, this::fireValueChanged) + valuesReadingContext: ValuesReadingContext, + labelText: String? = null, + initialValue: String? = null, + validator: SettingValidator? = null, + onValueUpdate: (String) -> Unit = {} +) : UIComponent( + valuesReadingContext, + labelText, + validator, + onValueUpdate +) { + override val uiComponent: JBTextField = textField(initialValue.orEmpty(), ::fireValueUpdated) - override val component: JComponent = panel { - add(validationIndicator, BorderLayout.NORTH) - add(textField, BorderLayout.CENTER) + override fun updateUiValue(newValue: String) = safeUpdateUi { + uiComponent.text = newValue } - - var value: String - get() = textField.text - set(value) { - textField.text = value - fireValueChanged(value) - } - - private fun fireValueChanged(text: String) { - validate(text) - if (validationIndicator.validationState == ValidationResult.OK) { - onSuccessValueUpdate(text) - } - onAnyValueUpdate(text) - } - - override fun onInit() { - super.onInit() - validate(initialText) - } - - private fun validate(text: String) { - validationIndicator.validationState = validator.validate(valuesReadingContext, text) - } + override fun getUiValue(): String = uiComponent.text } \ No newline at end of file diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/UIComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/UIComponent.kt new file mode 100644 index 00000000000..485adae97b3 --- /dev/null +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/components/UIComponent.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components + +import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext +import org.jetbrains.kotlin.tools.projectWizard.core.entity.Setting +import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingType +import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingValidator +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.DynamicComponent +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator +import java.awt.BorderLayout +import javax.swing.JComponent + +abstract class UIComponent( + private val valuesReadingContext: ValuesReadingContext, + labelText: String? = null, + private val validator: SettingValidator? = null, + private val onValueUpdate: (V) -> Unit = {} +) : DynamicComponent(valuesReadingContext) { + private val validationIndicator = if (validator != null) + ValidationIndicator(defaultText = labelText, showText = true) + else null + + protected abstract val uiComponent: JComponent + + abstract fun updateUiValue(newValue: V) + abstract fun getUiValue(): V + + private var allowEventFiring = true + + protected fun fireValueUpdated(value: V) { + if (allowEventFiring) { + onValueUpdate(value) + } + validate(value) + } + + override fun onInit() { + super.onInit() + validate(getUiValue()) + } + + final override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { + panel { + validationIndicator?.let { add(it, BorderLayout.NORTH) } + add(uiComponent, BorderLayout.CENTER) + } + } + + protected fun safeUpdateUi(updater: () -> Unit) { + val allowEventFiringSaved = allowEventFiring + allowEventFiring = false + updater() + allowEventFiring = allowEventFiringSaved + } + + fun validate(value: V) { + if (validator == null) return + if (validationIndicator == null) return + validationIndicator.validationState = validator.validate(valuesReadingContext, value) + } +} + +fun UIComponent.valueForSetting(setting: Setting>): V = + setting.defaultValue ?: getUiValue() \ No newline at end of file diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/firstStep/BuildSystemTypeSettingComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/firstStep/BuildSystemTypeSettingComponent.kt index a6fa17d1d0e..ee3e90ae75c 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/firstStep/BuildSystemTypeSettingComponent.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/firstStep/BuildSystemTypeSettingComponent.kt @@ -11,39 +11,37 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemP import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.DropDownComponent +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.valueForSetting import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.UIComponentDelegatingSettingComponent import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator import java.awt.BorderLayout class BuildSystemTypeSettingComponent( private val valuesReadingContext: ValuesReadingContext -) : SettingComponent>( +) : UIComponentDelegatingSettingComponent>( BuildSystemPlugin::type.reference, valuesReadingContext ) { - override val validationIndicator: ValidationIndicator? = null - private val listComponent = DropDownComponent( + override val uiComponent: DropDownComponent = DropDownComponent( valuesReadingContext, setting.type.values, labelText = "Build System", filter = { value -> setting.type.filter(valuesReadingContext, reference, value) }, validator = setting.validator, iconProvider = BuildSystemType::icon, - onAnyValueUpdate = { value = it } + onValueUpdate = { value = it } ).asSubComponent() - override val component = panel { - add(listComponent.component, BorderLayout.CENTER) - } override fun onValueUpdated(reference: SettingReference<*, *>?) { super.onValueUpdated(reference) if (reference == KotlinPlugin::projectKind.reference) { - listComponent.component.updateUI() + uiComponent.component.updateUI() } - listComponent.validate() + value?.let(uiComponent::validate) } } diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/secondStep/ModuleSettingsComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/secondStep/ModuleSettingsComponent.kt index d4ca1e912be..a2f3d610f73 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/secondStep/ModuleSettingsComponent.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/secondStep/ModuleSettingsComponent.kt @@ -24,7 +24,7 @@ class ModuleSettingsComponent(valuesReadingContext: ValuesReadingContext) : Dyna private val nameField = TextFieldComponent( valuesReadingContext, labelText = "Name", - onAnyValueUpdate = { value -> + onValueUpdate = { value -> module?.name = value eventManager.fireListeners(null) }, @@ -52,7 +52,7 @@ class ModuleSettingsComponent(valuesReadingContext: ValuesReadingContext) : Dyna } private fun updateModule(module: Module) { - nameField.value = module.name + nameField.updateUiValue(module.name) nameField.component.isVisible = module.kind != ModuleKind.target || module.configurator.moduleType != ModuleType.common diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/DefaultSettingComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/DefaultSettingComponent.kt index 6af8847c425..83fe30c47a9 100644 --- a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/DefaultSettingComponent.kt +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/DefaultSettingComponent.kt @@ -1,69 +1,59 @@ package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting import com.intellij.openapi.ui.ComboBox -import com.intellij.ui.components.JBCheckBox import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext -import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem import org.jetbrains.kotlin.tools.projectWizard.core.entity.* +import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.DropDownComponent -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.PathFieldComponent -import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.TextFieldComponent +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.* import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel import java.awt.BorderLayout import java.awt.event.ItemEvent import java.nio.file.Path -import java.nio.file.Paths import javax.swing.DefaultComboBoxModel import javax.swing.JComponent -sealed class DefaultSettingComponent>( - reference: SettingReference, - valuesReadingContext: ValuesReadingContext -) : SettingComponent(reference, valuesReadingContext) { - companion object { - @Suppress("UNCHECKED_CAST") - fun > create( - setting: SettingReference, - valuesReadingContext: ValuesReadingContext - ): DefaultSettingComponent = when (setting.type) { - VersionSettingType::class -> - VersionSettingComponent( - setting as SettingReference, - valuesReadingContext - ) as DefaultSettingComponent - BooleanSettingType::class -> - BooleanSettingComponent( - setting as SettingReference, - valuesReadingContext - ) as DefaultSettingComponent - DropDownSettingType::class -> - DropdownSettingComponent( - setting as SettingReference>, - valuesReadingContext - ) as DefaultSettingComponent - StringSettingType::class -> - StringSettingComponent( - setting as SettingReference, - valuesReadingContext - ) as DefaultSettingComponent - PathSettingType::class -> - PathSettingComponent( - setting as SettingReference, - valuesReadingContext - ) as DefaultSettingComponent - else -> TODO(setting.type.qualifiedName!!) - } +object DefaultSettingComponent { + @Suppress("UNCHECKED_CAST") + fun > create( + setting: SettingReference, + valuesReadingContext: ValuesReadingContext + ): SettingComponent = when (setting.type) { + VersionSettingType::class -> + VersionSettingComponent( + setting as SettingReference, + valuesReadingContext + ) as SettingComponent + BooleanSettingType::class -> + BooleanSettingComponent( + setting as SettingReference, + valuesReadingContext + ) as SettingComponent + DropDownSettingType::class -> + DropdownSettingComponent( + setting as SettingReference>, + valuesReadingContext + ) as SettingComponent + StringSettingType::class -> + StringSettingComponent( + setting as SettingReference, + valuesReadingContext + ) as SettingComponent + PathSettingType::class -> + PathSettingComponent( + setting as SettingReference, + valuesReadingContext + ) as SettingComponent + else -> TODO(setting.type.qualifiedName!!) } } - class VersionSettingComponent( reference: SettingReference, valuesReadingContext: ValuesReadingContext -) : DefaultSettingComponent(reference, valuesReadingContext) { +) : SettingComponent(reference, valuesReadingContext) { private val settingLabel = label(setting.title) private val comboBox = ComboBox().apply { addItemListener { e -> @@ -98,94 +88,68 @@ class VersionSettingComponent( } } + class DropdownSettingComponent( reference: SettingReference>, private val valuesReadingContext: ValuesReadingContext -) : DefaultSettingComponent>( +) : UIComponentDelegatingSettingComponent>( reference, valuesReadingContext ) { - private val dropDownComponent = DropDownComponent( - valuesReadingContext, - setting.type.values, + override val uiComponent = DropDownComponent( + valuesReadingContext = valuesReadingContext, + initialValues = setting.type.values, + validator = setting.validator, filter = { value -> setting.type.filter(valuesReadingContext, reference, value) }, labelText = setting.title, - onAnyValueUpdate = { newValue -> - value = newValue - } + onValueUpdate = { newValue -> value = newValue } ).asSubComponent() - - override val validationIndicator: ValidationIndicator? = null - override val component: JComponent = dropDownComponent.component } class BooleanSettingComponent( reference: SettingReference, valuesReadingContext: ValuesReadingContext -) : DefaultSettingComponent(reference, valuesReadingContext) { - private val checkBox = JBCheckBox(setting.title).apply { - addChangeListener { - value = this@apply.isSelected - } - } - - override fun onValueUpdated(reference: SettingReference<*, *>?) { - super.onValueUpdated(reference) - checkBox.isSelected = value ?: false - } - - override val validationIndicator = ValidationIndicator(showText = false) - - override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { - panel { - // TODO add validation indicator - add(checkBox, BorderLayout.CENTER) - } - } +) : UIComponentDelegatingSettingComponent( + reference, + valuesReadingContext +) { + override val uiComponent = CheckboxComponent( + valuesReadingContext = valuesReadingContext, + labelText = setting.title, + initialValue = null, + validator = setting.validator, + onValueUpdate = { newValue -> value = newValue } + ).asSubComponent() } class StringSettingComponent( reference: SettingReference, valuesReadingContext: ValuesReadingContext, showLabel: Boolean = true -) : DefaultSettingComponent(reference, valuesReadingContext) { - private val textFieldComponent = TextFieldComponent( - valuesReadingContext, - setting.defaultValue.orEmpty(), +) : UIComponentDelegatingSettingComponent( + reference, + valuesReadingContext +) { + override val uiComponent = TextFieldComponent( + valuesReadingContext = valuesReadingContext, + initialValue = null, labelText = if (showLabel) setting.title else null, validator = setting.validator, - onAnyValueUpdate = { - value = it - } + onValueUpdate = { newValue -> value = newValue } ).asSubComponent() - - override val validationIndicator: ValidationIndicator? = null - - override fun onInit() { - super.onInit() - textFieldComponent.value = value.orEmpty() - } - - override val component = textFieldComponent.component } class PathSettingComponent( reference: SettingReference, valuesReadingContext: ValuesReadingContext -) : DefaultSettingComponent(reference, valuesReadingContext) { - private val pathFieldComponent = PathFieldComponent( - valuesReadingContext, - "", - setting.title, - validator = settingValidator { path -> - setting.validator.validate(this, Paths.get(path)) - }, - onAnyValueUpdate = { - value = Paths.get(it) - } +) : UIComponentDelegatingSettingComponent( + reference, + valuesReadingContext +) { + override val uiComponent = PathFieldComponent( + valuesReadingContext = valuesReadingContext, + labelText = setting.title, + validator = settingValidator { path -> setting.validator.validate(this, path) }, + onValueUpdate = { newValue -> value = newValue } ).asSubComponent() - - override val validationIndicator: ValidationIndicator? = null - - override val component = pathFieldComponent.component } \ No newline at end of file diff --git a/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/UIComponentDelegatingSettingComponent.kt b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/UIComponentDelegatingSettingComponent.kt new file mode 100644 index 00000000000..45f82cd42ec --- /dev/null +++ b/idea/idea-new-project-wizard/src/org/jetbrains/kotlin/tools/projectWizard/wizard/ui/setting/UIComponentDelegatingSettingComponent.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting + +import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext +import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingReference +import org.jetbrains.kotlin.tools.projectWizard.core.entity.SettingType +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.UIComponent +import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.valueForSetting +import javax.swing.JComponent + +abstract class UIComponentDelegatingSettingComponent>( + reference: SettingReference, + valuesReadingContext: ValuesReadingContext +) : SettingComponent(reference, valuesReadingContext) { + abstract val uiComponent: UIComponent + + // As there is one in UIComponent + override val validationIndicator: ValidationIndicator? = null + + override fun onInit() { + super.onInit() + if (value == null) { + if (value == null) { + value = uiComponent.valueForSetting(setting) + } + } + value?.let(uiComponent::updateUiValue) + } + + override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) { uiComponent.component } +} \ No newline at end of file