11package org.digma.intellij.plugin.ui.common
22
3+ import com.intellij.openapi.diagnostic.Logger
34import com.intellij.openapi.project.Project
45import com.intellij.ui.components.ActionLink
56import com.intellij.ui.components.JBLabel
@@ -11,8 +12,10 @@ import com.intellij.util.ui.JBUI
1112import com.intellij.util.ui.WrapLayout
1213import org.digma.intellij.plugin.analytics.AnalyticsService
1314import org.digma.intellij.plugin.analytics.EnvironmentChanged
15+ import org.digma.intellij.plugin.common.Backgroundable
1416import org.digma.intellij.plugin.common.CommonUtils
1517import org.digma.intellij.plugin.common.CommonUtils.prettyTimeOf
18+ import org.digma.intellij.plugin.log.Log
1619import org.digma.intellij.plugin.model.rest.usage.UsageStatusResult
1720import org.digma.intellij.plugin.ui.common.Laf.Icons.Environment.Companion.ENVIRONMENT_HAS_NO_USAGE
1821import org.digma.intellij.plugin.ui.common.Laf.Icons.Environment.Companion.ENVIRONMENT_HAS_USAGE
@@ -24,6 +27,7 @@ import java.awt.Dimension
2427import java.awt.FlowLayout
2528import java.lang.Integer.max
2629import java.util.*
30+ import java.util.concurrent.locks.ReentrantLock
2731import java.util.function.Function
2832import javax.swing.Icon
2933import javax.swing.JComponent
@@ -36,14 +40,20 @@ class EnvironmentsPanel(
3640 private val model : PanelModel ,
3741 private val environmentsSupplier : EnvironmentsSupplier , // assuming its a singleton
3842) : DigmaResettablePanel() {
43+ private val logger: Logger = Logger .getInstance(EnvironmentsPanel ::class .java)
3944
45+ private val project: Project
4046 private val changeEnvAlarm: Alarm
47+ private val localHostname: String
48+ private val rebuildPanelLock = ReentrantLock ()
4149
4250 init {
51+ this .project = project
4352 changeEnvAlarm = AlarmFactory .getInstance().create()
53+ localHostname = CommonUtils .getLocalHostname()
4454 isOpaque = false
4555 layout = WrapLayout (FlowLayout .LEFT , 2 , 0 )
46- rebuild( )
56+ rebuildInBackground(project )
4757
4858 project.messageBus.connect(project.getService(AnalyticsService ::class .java))
4959 .subscribe(EnvironmentChanged .ENVIRONMENT_CHANGED_TOPIC , object : EnvironmentChanged {
@@ -61,10 +71,10 @@ class EnvironmentsPanel(
6171
6272 override fun environmentsListChanged (newEnvironments : MutableList <String >? ) {
6373 if (SwingUtilities .isEventDispatchThread()) {
64- rebuild( )
74+ rebuildInBackground(project )
6575 } else {
6676 SwingUtilities .invokeLater {
67- rebuild( )
77+ rebuildInBackground(project )
6878 }
6979 }
7080 }
@@ -73,7 +83,7 @@ class EnvironmentsPanel(
7383
7484
7585 override fun reset () {
76- rebuild( )
86+ rebuildInBackground(project )
7787 }
7888
7989 /*
@@ -143,6 +153,20 @@ class EnvironmentsPanel(
143153
144154 }
145155
156+ private fun rebuildInBackground (project : Project ) {
157+ val task = Runnable {
158+ rebuildPanelLock.lock()
159+ Log .log(logger::debug, " Lock acquired for rebuild Envs panel process." )
160+ try {
161+ rebuild()
162+ } finally {
163+ rebuildPanelLock.unlock()
164+ Log .log(logger::debug, " Lock released for rebuild Envs panel process." )
165+ }
166+ }
167+ Backgroundable .ensureBackground(project, " Rebuilding environments panel" , task)
168+ }
169+
146170 private fun rebuild () {
147171
148172 if (components.isNotEmpty()) {
@@ -163,39 +187,50 @@ class EnvironmentsPanel(
163187 val isSelectedEnv = currEnv.contentEquals(environmentsSupplier.getCurrent())
164188 val toolTip = buildToolTip(usageStatusResult, currEnv)
165189 val linkText = buildLinkText(currEnv, isSelectedEnv)
166- val envLink = EnvLink (currEnv, linkText, isSelectedEnv)
167- envLink.toolTipText = toolTip
168190
169- envLink.addActionListener() { event ->
170-
171- val currentSelected: EnvLink ? = getSelected()
172-
173- if (currentSelected == = event.source) {
174- return @addActionListener
191+ if (SwingUtilities .isEventDispatchThread()) {
192+ buildEnvironmentsPanelButtons(currEnv, linkText, isSelectedEnv, toolTip, hasUsageFunction)
193+ } else {
194+ SwingUtilities .invokeLater {
195+ buildEnvironmentsPanelButtons(currEnv, linkText, isSelectedEnv, toolTip, hasUsageFunction)
175196 }
197+ }
198+ }
199+ revalidate()
200+ }
176201
177- currentSelected?.deselect { buildLinkText(it, false ) }
202+ private fun buildEnvironmentsPanelButtons (currEnv : String , linkText : String , isSelectedEnv : Boolean ,
203+ toolTip : String , hasUsageFunction : (String ) -> Boolean ) {
204+ val envLink = EnvLink (currEnv, linkText, isSelectedEnv)
205+ envLink.toolTipText = toolTip
178206
179- val clickedLink: EnvLink = event.source as EnvLink
180- clickedLink.select { buildLinkText(it, true ) }
207+ envLink.addActionListener { event ->
181208
182- changeEnvAlarm.cancelAllRequests()
183- changeEnvAlarm.addRequest({
184- environmentsSupplier.setCurrent(clickedLink.env)
185- }, 100 )
209+ val currentSelected: EnvLink ? = getSelected()
186210
211+ if (currentSelected == = event.source) {
212+ return @addActionListener
187213 }
188214
189- val icon: Icon =
190- if (hasUsageFunction(currEnv)) ENVIRONMENT_HAS_USAGE else ENVIRONMENT_HAS_NO_USAGE
191- val iconComponent = JBLabel (icon)
215+ currentSelected?.deselect { buildLinkText(it, false ) }
216+
217+ val clickedLink: EnvLink = event.source as EnvLink
218+ clickedLink.select { buildLinkText(it, true ) }
192219
193- val singlePanel = SingleEnvPanel (envLink, iconComponent)
194- singlePanel.toolTipText = toolTip
220+ changeEnvAlarm.cancelAllRequests()
221+ changeEnvAlarm.addRequest({
222+ environmentsSupplier.setCurrent(clickedLink.env)
223+ }, 100 )
195224
196- this .add(singlePanel)
197225 }
198- revalidate()
226+
227+ val icon: Icon = if (hasUsageFunction(currEnv)) ENVIRONMENT_HAS_USAGE else ENVIRONMENT_HAS_NO_USAGE
228+ val iconComponent = JBLabel (icon)
229+
230+ val singlePanel = SingleEnvPanel (envLink, iconComponent)
231+ singlePanel.toolTipText = toolTip
232+
233+ this .add(singlePanel)
199234 }
200235
201236 private fun getSelected (): EnvLink ? {
@@ -205,8 +240,8 @@ class EnvironmentsPanel(
205240 return currentSelectedPanel?.myLink
206241 }
207242
208- fun buildToolTip (usageStatusResult : UsageStatusResult , envName : String ): String {
209- val envUsageStatus = usageStatusResult.environmentStatuses.firstOrNull { it.name.equals( envName) }
243+ private fun buildToolTip (usageStatusResult : UsageStatusResult , envName : String ): String {
244+ val envUsageStatus = usageStatusResult.environmentStatuses.firstOrNull { it.name == envName }
210245 val sb = StringBuilder ()
211246 sb.append(envName)
212247 if (envUsageStatus != null ) {
@@ -220,13 +255,13 @@ class EnvironmentsPanel(
220255 return asHtml(sb.toString())
221256 }
222257
223- fun buildEnvironmentWithUsages (usageStatusResult : UsageStatusResult ): Set <String > {
258+ private fun buildEnvironmentWithUsages (usageStatusResult : UsageStatusResult ): Set <String > {
224259 return usageStatusResult.codeObjectStatuses
225260 .map { it.environment }
226261 .toSet()
227262 }
228263
229- fun buildRelevantSortedEnvironments (
264+ private fun buildRelevantSortedEnvironments (
230265 envsSupplier : EnvironmentsSupplier ,
231266 hasUsageFun : (String ) -> Boolean
232267 ): List <String > {
@@ -278,7 +313,6 @@ class EnvironmentsPanel(
278313 }
279314
280315 private fun isLocalEnvironmentMine (environment : String ): Boolean {
281- val localHostname = CommonUtils .getLocalHostname()
282316 return environment.startsWith(localHostname, true )
283317 }
284318
0 commit comments