@@ -56,6 +56,7 @@ import kotlinx.coroutines.Dispatchers
5656import kotlinx.coroutines.Job
5757import kotlinx.coroutines.cancel
5858import kotlinx.coroutines.launch
59+ import kotlinx.coroutines.withContext
5960
6061/* *
6162 * The step to select a custom template repo.
@@ -219,7 +220,7 @@ class CustomPlatformStep(
219220 val indicator = CreatorProgressIndicator (
220221 templateProvidersLoadingProperty,
221222 templateProvidersTextProperty,
222- templateProvidersText2Property
223+ templateProvidersText2Property,
223224 )
224225
225226 templateProvidersTextProperty.set(MCDevBundle (" creator.step.generic.init_template_providers.message" ))
@@ -233,18 +234,24 @@ class CustomPlatformStep(
233234
234235 val dialogCoroutineContext = context.modalityState.asContextElement()
235236 val uiContext = dialogCoroutineContext + Dispatchers .EDT
236- creatorUiScope.launch(uiContext) {
237- for ((providerKey, repos) in templateRepos.groupBy { it.provider }) {
238- val provider = TemplateProvider .get(providerKey)
239- ? : continue
240- indicator.text = provider.label
241- runCatching { provider.init (indicator, repos) }
242- .getOrLogException(logger<CustomPlatformStep >())
237+ creatorUiScope.launch(dialogCoroutineContext) {
238+ // provider.init() downloads/reads files, so run in the background
239+ withContext(Dispatchers .Default ) {
240+ for ((providerKey, repos) in templateRepos.groupBy { it.provider }) {
241+ val provider = TemplateProvider .get(providerKey)
242+ ? : continue
243+ // indicator.text is a PropertyGraph property, so set it on EDT.
244+ withContext(uiContext) { indicator.text = provider.label }
245+ runCatching { provider.init (indicator, repos) }
246+ .getOrLogException(logger<CustomPlatformStep >())
247+ }
243248 }
244249
245- templateProvidersLoadingProperty.set(false )
246- // Force refresh to trigger template loading
247- templateRepoProperty.set(templateRepo)
250+ withContext(uiContext) {
251+ templateProvidersLoadingProperty.set(false )
252+ // Force refresh to trigger template loading
253+ templateRepoProperty.set(templateRepo)
254+ }
248255 }
249256 }
250257
@@ -263,19 +270,25 @@ class CustomPlatformStep(
263270 val dialogCoroutineContext = context.modalityState.asContextElement()
264271 val uiContext = dialogCoroutineContext + Dispatchers .EDT
265272 templateLoadingJob?.cancel(" Another template has been selected" )
266- templateLoadingJob = creatorUiScope.launch(uiContext) {
267- val newTemplates = runCatching { provider() }
268- .getOrLogException(logger<CustomPlatformStep >())
269- ? : emptyList()
270-
271- templateLoadingProperty.set(false )
272- noTemplatesAvailable.visible(newTemplates.isEmpty())
273- if (newTemplates.any { checkInvalidVersionTemplate(it) }) {
274- availableTemplates = emptyList()
275- invalidTemplateVersion.visible(true )
276- } else {
277- availableTemplates = newTemplates
278- invalidTemplateVersion.visible(false )
273+ templateLoadingJob = creatorUiScope.launch(dialogCoroutineContext) {
274+ // Run slow VFS/IO work on a background thread, not the EDT.
275+ val newTemplates = withContext(Dispatchers .Default ) {
276+ runCatching { provider() }
277+ .getOrLogException(logger<CustomPlatformStep >())
278+ ? : emptyList()
279+ }
280+
281+ // Switch to EDT only for UI property mutations.
282+ withContext(uiContext) {
283+ templateLoadingProperty.set(false )
284+ noTemplatesAvailable.visible(newTemplates.isEmpty())
285+ if (newTemplates.any { checkInvalidVersionTemplate(it) }) {
286+ availableTemplates = emptyList()
287+ invalidTemplateVersion.visible(true )
288+ } else {
289+ availableTemplates = newTemplates
290+ invalidTemplateVersion.visible(false )
291+ }
279292 }
280293 }
281294 }
0 commit comments