From 1ad48d35aa2b7294c5975d47af27b85e12060f65 Mon Sep 17 00:00:00 2001 From: Sergei Vorobyov Date: Tue, 5 May 2020 17:24:32 +0300 Subject: [PATCH] IDEA-238573 removed cyclic update of UI components that bound with properties GitOrigin-RevId: 424aab4a0c8f9fccadac8af1747ace360d5e82eb --- .../src/com/intellij/ui/layout/Cell.kt | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/layout/Cell.kt b/platform/platform-impl/src/com/intellij/ui/layout/Cell.kt index f1ea96a4ad17..cd672936efd8 100644 --- a/platform/platform-impl/src/com/intellij/ui/layout/Cell.kt +++ b/platform/platform-impl/src/com/intellij/ui/layout/Cell.kt @@ -31,6 +31,7 @@ import java.awt.event.ActionListener import java.awt.event.ItemEvent import java.awt.event.MouseEvent import java.util.* +import java.util.concurrent.atomic.AtomicBoolean import javax.swing.* import javax.swing.event.DocumentEvent import kotlin.jvm.internal.CallableReference @@ -539,11 +540,18 @@ fun listCellRenderer(renderer: SimpleListCellRenderer.(value: T, index: } private fun ComboBox.bind(property: GraphProperty) { - property.afterChange { if (selectedItem != it) selectedItem = it } + val mutex = AtomicBoolean() + property.afterChange { + mutex.lockOrSkip { + selectedItem = it + } + } addItemListener { if (it.stateChange == ItemEvent.SELECTED) { - @Suppress("UNCHECKED_CAST") - property.set(it.item as T) + mutex.lockOrSkip { + @Suppress("UNCHECKED_CAST") + property.set(it.item as T) + } } } } @@ -553,16 +561,33 @@ private fun TextFieldWithBrowseButton.bind(property: GraphProperty) { } private fun JTextField.bind(property: GraphProperty) { - property.afterChange { if (text != it) text = it } + val mutex = AtomicBoolean() + property.afterChange { + mutex.lockOrSkip { + text = it + } + } document.addDocumentListener( object : DocumentAdapter() { override fun textChanged(e: DocumentEvent) { - property.set(text) + mutex.lockOrSkip { + property.set(text) + } } } ) } +private fun AtomicBoolean.lockOrSkip(action: () -> Unit) { + if (!compareAndSet(false, true)) return + try { + action() + } + finally { + set(false) + } +} + fun Cell.slider(min: Int, max: Int, minorTick: Int, majorTick: Int): CellBuilder { val slider = JSlider() UIUtil.setSliderIsFilled(slider, true)