Wizard: use IntelliJ validator in UI instead of custom one
This commit is contained in:
+3
-1
@@ -41,7 +41,9 @@ class PathFieldComponent(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateUiValue(newValue: Path)= safeUpdateUi {
|
override fun getValidatorTarget(): JComponent = uiComponent.textField
|
||||||
|
|
||||||
|
override fun updateUiValue(newValue: Path) = safeUpdateUi {
|
||||||
uiComponent.text = newValue.toString()
|
uiComponent.text = newValue.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-6
@@ -5,12 +5,15 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components
|
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components
|
||||||
|
|
||||||
|
import com.intellij.openapi.Disposable
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext
|
import org.jetbrains.kotlin.tools.projectWizard.core.ValuesReadingContext
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
|
import org.jetbrains.kotlin.tools.projectWizard.core.entity.*
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.DynamicComponent
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.DynamicComponent
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.FocusableComponent
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.FocusableComponent
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ErrorAwareComponent
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ErrorAwareComponent
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.IdeaBasedComponentValidator
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
@@ -21,13 +24,19 @@ abstract class UIComponent<V : Any>(
|
|||||||
labelText: String? = null,
|
labelText: String? = null,
|
||||||
private val validator: SettingValidator<V>? = null,
|
private val validator: SettingValidator<V>? = null,
|
||||||
private val onValueUpdate: (V) -> Unit = {}
|
private val onValueUpdate: (V) -> Unit = {}
|
||||||
) : DynamicComponent(valuesReadingContext), ErrorAwareComponent, FocusableComponent {
|
) : DynamicComponent(valuesReadingContext), ErrorAwareComponent, FocusableComponent, Disposable {
|
||||||
private val validationIndicator = if (validator != null)
|
private val validationIndicator by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
ValidationIndicator(defaultText = labelText, showText = true)
|
if (validator != null)
|
||||||
else null
|
IdeaBasedComponentValidator(this, getValidatorTarget())
|
||||||
|
else null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {}
|
||||||
|
|
||||||
protected abstract val uiComponent: JComponent
|
protected abstract val uiComponent: JComponent
|
||||||
|
|
||||||
|
protected open fun getValidatorTarget() = uiComponent
|
||||||
|
|
||||||
abstract fun updateUiValue(newValue: V)
|
abstract fun updateUiValue(newValue: V)
|
||||||
abstract fun getUiValue(): V?
|
abstract fun getUiValue(): V?
|
||||||
|
|
||||||
@@ -47,7 +56,7 @@ abstract class UIComponent<V : Any>(
|
|||||||
|
|
||||||
final override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
|
final override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
panel {
|
panel {
|
||||||
validationIndicator?.let { add(it, BorderLayout.NORTH) }
|
labelText?.let { add(label("$it:"), BorderLayout.NORTH) }
|
||||||
add(uiComponent, BorderLayout.CENTER)
|
add(uiComponent, BorderLayout.CENTER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +71,7 @@ abstract class UIComponent<V : Any>(
|
|||||||
fun validate(value: V) {
|
fun validate(value: V) {
|
||||||
if (validator == null) return
|
if (validator == null) return
|
||||||
if (validationIndicator == null) return
|
if (validationIndicator == null) return
|
||||||
validationIndicator.validationState = validator.validate(valuesReadingContext, value)
|
validationIndicator?.updateValidationState(validator.validate(valuesReadingContext, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun focusOn() {
|
override fun focusOn() {
|
||||||
|
|||||||
+3
-5
@@ -11,8 +11,8 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ProjectKind
|
|||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
|
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.panel
|
||||||
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.AlwaysShownValidationIndicator
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator
|
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
import javax.swing.BorderFactory
|
import javax.swing.BorderFactory
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
@@ -66,11 +66,9 @@ class ModulesEditorComponent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val validationIndicator = ValidationIndicator(showText = true) { error ->
|
override val validationIndicator = AlwaysShownValidationIndicator(showText = true) { error ->
|
||||||
val module = error.target as? Module ?: return@ValidationIndicator
|
val module = error.target as? Module ?: return@AlwaysShownValidationIndicator
|
||||||
tree.selectModule(module)
|
tree.selectModule(module)
|
||||||
selectSettingWithError(error)
|
selectSettingWithError(error)
|
||||||
}.apply {
|
|
||||||
background = tree.background
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -73,12 +73,11 @@ class VersionSettingComponent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val validationIndicator = ValidationIndicator(showText = false)
|
override val validationIndicator = null
|
||||||
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
|
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
panel {
|
panel {
|
||||||
add(
|
add(
|
||||||
panel {
|
panel {
|
||||||
add(validationIndicator, BorderLayout.WEST)
|
|
||||||
add(settingLabel, BorderLayout.CENTER)
|
add(settingLabel, BorderLayout.CENTER)
|
||||||
},
|
},
|
||||||
BorderLayout.WEST
|
BorderLayout.WEST
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ abstract class SettingComponent<V : Any, T: SettingType<V>>(
|
|||||||
private fun updateValidationState() {
|
private fun updateValidationState() {
|
||||||
val value = value
|
val value = value
|
||||||
if (validationIndicator != null && value != null) {
|
if (validationIndicator != null && value != null) {
|
||||||
validationIndicator!!.validationState = setting.validator.validate(valuesReadingContext, value)
|
validationIndicator!!.updateValidationState(setting.validator.validate(valuesReadingContext, value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+47
-40
@@ -1,35 +1,57 @@
|
|||||||
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting
|
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting
|
||||||
|
|
||||||
import com.intellij.icons.AllIcons
|
import com.intellij.icons.AllIcons
|
||||||
import com.intellij.ui.JBColor
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.util.ui.EmptyIcon
|
import com.intellij.openapi.ui.ComponentValidator
|
||||||
|
import com.intellij.openapi.ui.ValidationInfo
|
||||||
|
import com.intellij.util.ui.JBUI
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
|
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.asHtml
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.label
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import java.awt.BorderLayout
|
import java.awt.BorderLayout
|
||||||
import java.awt.Cursor
|
import java.awt.Cursor
|
||||||
import java.awt.event.MouseEvent
|
import java.awt.event.MouseEvent
|
||||||
import java.awt.event.MouseListener
|
import java.awt.event.MouseListener
|
||||||
import javax.swing.BorderFactory
|
import javax.swing.BorderFactory
|
||||||
import javax.swing.Icon
|
import javax.swing.JComponent
|
||||||
import javax.swing.JPanel
|
import javax.swing.JPanel
|
||||||
|
|
||||||
class ValidationIndicator(
|
interface ValidationIndicator {
|
||||||
defaultText: String? = null,
|
fun updateValidationState(newState: ValidationResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
class IdeaBasedComponentValidator(
|
||||||
|
parentDisposable: Disposable,
|
||||||
|
private val jComponent: JComponent
|
||||||
|
) : ValidationIndicator {
|
||||||
|
private val validator = ComponentValidator(parentDisposable).installOn(jComponent)
|
||||||
|
|
||||||
|
override fun updateValidationState(newState: ValidationResult) {
|
||||||
|
validator.updateInfo(
|
||||||
|
newState.safeAs<ValidationResult.ValidationError>()
|
||||||
|
?.messages
|
||||||
|
?.firstOrNull()
|
||||||
|
?.let { ValidationInfo(it, jComponent) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AlwaysShownValidationIndicator(
|
||||||
private val showText: Boolean,
|
private val showText: Boolean,
|
||||||
private val onClickAction: ((ValidationResult.ValidationError) -> Unit)? = null
|
private val onClickAction: ((ValidationResult.ValidationError) -> Unit)? = null
|
||||||
) : JPanel(BorderLayout()) {
|
) : JPanel(BorderLayout()), ValidationIndicator {
|
||||||
private val textLabel = defaultText?.let { label("$it: ") }
|
private val errorLabel = label(" ")
|
||||||
private val errorLabel = label(" ").apply {
|
|
||||||
foreground = JBColor.red
|
|
||||||
}
|
|
||||||
|
|
||||||
private var currentError: ValidationResult.ValidationError? = null
|
private var currentError: ValidationResult.ValidationError? = null
|
||||||
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
border = BorderFactory.createEmptyBorder(3, 3, 3, 3)
|
errorLabel.icon = AllIcons.General.Error
|
||||||
textLabel?.let { add(it, BorderLayout.WEST) }
|
background = JBUI.CurrentTheme.Validator.errorBackgroundColor()
|
||||||
|
border =
|
||||||
|
BorderFactory.createCompoundBorder(
|
||||||
|
BorderFactory.createLineBorder(JBUI.CurrentTheme.Validator.errorBorderColor()),
|
||||||
|
JBUI.Borders.empty(4, 8)
|
||||||
|
)
|
||||||
add(errorLabel, BorderLayout.CENTER)
|
add(errorLabel, BorderLayout.CENTER)
|
||||||
|
|
||||||
if (onClickAction != null) {
|
if (onClickAction != null) {
|
||||||
@@ -47,32 +69,17 @@ class ValidationIndicator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setIcon(icon: Icon?) {
|
override fun updateValidationState(newState: ValidationResult) {
|
||||||
if (textLabel != null) textLabel.icon = icon
|
isVisible = !newState.isOk
|
||||||
else errorLabel.icon = icon ?: EmptyIcon.ICON_16
|
when (newState) {
|
||||||
}
|
ValidationResult.OK -> {
|
||||||
|
currentError = null
|
||||||
private fun String.linkifyErrorText() =
|
}
|
||||||
if (onClickAction == null) this
|
is ValidationResult.ValidationError -> {
|
||||||
else "<u>$this</u>".asHtml()
|
val errors = newState.messages.firstOrNull().orEmpty()
|
||||||
|
if (showText) errorLabel.text = errors
|
||||||
var validationState: ValidationResult = ValidationResult.OK
|
currentError = newState
|
||||||
set(value) {
|
|
||||||
field = value
|
|
||||||
when (value) {
|
|
||||||
ValidationResult.OK -> {
|
|
||||||
setIcon(null)
|
|
||||||
errorLabel.text = " "
|
|
||||||
toolTipText = null
|
|
||||||
currentError = null
|
|
||||||
}
|
|
||||||
is ValidationResult.ValidationError -> {
|
|
||||||
setIcon(AllIcons.General.Error)
|
|
||||||
val errors = value.messages.firstOrNull().orEmpty()
|
|
||||||
toolTipText = errors
|
|
||||||
if (showText) errorLabel.text = errors.linkifyErrorText()
|
|
||||||
currentError = value
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user