how to use a TextFieldWithCompletion inside of a configuration window that was build with the form builder ?

Answered

Hi All,

 

I have a class that implements Configurable and that is working as expected.

I replaced one combobox with a TextFieldWithCompletion and I get some nasty exception when opening the settings menu

 

Details: Current thread: Thread[ApplicationImpl pooled thread 5,4,Idea Thread Group] 2095649749
; dispatch thread: false; isDispatchThread(): false
SystemEventQueueThread: Thread[AWT-EventQueue-0,6,Idea Thread Group] 2135078772

java.lang.Throwable: Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())
at com.intellij.openapi.diagnostic.Logger.error(Logger.java:162)
at com.intellij.openapi.application.impl.ApplicationImpl.assertReadAccessAllowed(ApplicationImpl.java:918)
at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.getDocument(FileDocumentManagerImpl.java:193)
at com.intellij.psi.impl.PsiDocumentManagerBase.getDocument(PsiDocumentManagerBase.java:167)
at com.intellij.ui.LanguageTextField.createDocument(LanguageTextField.java:100)
at com.intellij.ui.LanguageTextField$SimpleDocumentCreator.createDocument(LanguageTextField.java:80)
at com.intellij.ui.LanguageTextField.<init>(LanguageTextField.java:64)
at com.intellij.util.textCompletion.TextFieldWithCompletion.<init>(TextFieldWithCompletion.java:48)
at com.intellij.util.textCompletion.TextFieldWithCompletion.<init>(TextFieldWithCompletion.java:38)
at com.swissas.config.ConfigPanel.createUIComponents(ConfigPanel.java:120)
at com.swissas.config.ConfigPanel.$$$setupUI$$$(ConfigPanel.java)
at com.swissas.config.ConfigPanel.<init>(ConfigPanel.java:57)
at com.swissas.config.SwissAsConfig.<init>(SwissAsConfig.java:38)

 

here are some small code parts

 

my configurable

 

public SwissAsConfig(Project project){
this.project = project;
this.swissAsStorage = SwissAsStorage.getInstance();
this.configPanel = new ConfigPanel(this.project, this.swissAsStorage);
updateUIState();

 

the form builder is correctly configure to use a non palette component and is correctly binded to the TextFieldWithCompletion class

And of course I checked the custom create checkbox within the form builder.

Here is the builiding part : 

private void createUIComponents() {
...
StringsCompletionProvider allUserProvider = new StringsCompletionProvider(this.storage.getUserMap().keySet(), null);
this.fourLetterCode = new TextFieldWithCompletion(this.project, allUserProvider,"", true, true, true);
}



 

any Idea what I'm doing wrong ? 

some time I have the view that is correctly displayed and the TextFieldWithCompletion is also working like expected.

But sometime the UI stays in a loading state and I saw that I received the given exception

5 comments
Comment actions Permalink

Please, share whole stacktrace.

UI components should be created on Swing thread (aka Event Dispatch Thread/AWT/EDT), so the problem should be above SwissAsConfig constructor call.

0
Comment actions Permalink

full stacktrace.

 

I pushed my current state into https://github.com/alain57/swissas-dev-tools/tree/bugfix 

here is the full stack trace..

I really hope you can help me ;) 

Details: Current thread: Thread[ApplicationImpl pooled thread 361,4,Idea Thread Group] 1214877825
; dispatch thread: false; isDispatchThread(): false
SystemEventQueueThread: Thread[AWT-EventQueue-0,6,Idea Thread Group] 2003979044

java.lang.Throwable: Read access is allowed from event dispatch thread or inside read-action only (see com.intellij.openapi.application.Application.runReadAction())
at com.intellij.openapi.diagnostic.Logger.error(Logger.java:162)
at com.intellij.openapi.application.impl.ApplicationImpl.assertReadAccessAllowed(ApplicationImpl.java:918)
at com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl.getDocument(FileDocumentManagerImpl.java:193)
at com.intellij.psi.impl.PsiDocumentManagerBase.getDocument(PsiDocumentManagerBase.java:167)
at com.intellij.ui.LanguageTextField.createDocument(LanguageTextField.java:100)
at com.intellij.ui.LanguageTextField$SimpleDocumentCreator.createDocument(LanguageTextField.java:80)
at com.intellij.ui.LanguageTextField.<init>(LanguageTextField.java:64)
at com.intellij.util.textCompletion.TextFieldWithCompletion.<init>(TextFieldWithCompletion.java:48)
at com.swissas.config.ConfigPanel.createUIComponents(ConfigPanel.java:120)
at com.swissas.config.ConfigPanel.$$$setupUI$$$(ConfigPanel.java)
at com.swissas.config.ConfigPanel.<init>(ConfigPanel.java:60)
at com.swissas.config.SwissAsConfig.<init>(SwissAsConfig.java:38)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at org.picocontainer.defaults.InstantiatingComponentAdapter.newInstance(InstantiatingComponentAdapter.java:193)
at com.intellij.util.pico.CachingConstructorInjectionComponentAdapter.doGetComponentInstance(CachingConstructorInjectionComponentAdapter.java:91)
at com.intellij.util.pico.CachingConstructorInjectionComponentAdapter.instantiateGuarded(CachingConstructorInjectionComponentAdapter.java:69)
at com.intellij.util.pico.CachingConstructorInjectionComponentAdapter.getComponentInstance(CachingConstructorInjectionComponentAdapter.java:51)
at com.intellij.openapi.extensions.AbstractExtensionPointBean.instantiate(AbstractExtensionPointBean.java:103)
at com.intellij.openapi.extensions.AbstractExtensionPointBean.instantiate(AbstractExtensionPointBean.java:97)
at com.intellij.openapi.options.ConfigurableEP$ClassProducer.createElement(ConfigurableEP.java:387)
at com.intellij.openapi.options.ConfigurableEP.createConfigurable(ConfigurableEP.java:296)
at com.intellij.openapi.options.ex.ConfigurableWrapper.createConfigurable(ConfigurableWrapper.java:46)
at com.intellij.openapi.options.ex.ConfigurableWrapper.getConfigurable(ConfigurableWrapper.java:111)
at com.intellij.openapi.options.ex.ConfigurableWrapper.cast(ConfigurableWrapper.java:86)
at com.intellij.openapi.options.ex.ConfigurableCardPanel.prepare(ConfigurableCardPanel.java:43)
at com.intellij.openapi.options.ex.ConfigurableCardPanel.prepare(ConfigurableCardPanel.java:36)
at com.intellij.ui.CardLayoutPanel.lambda$selectLater$1(CardLayoutPanel.java:128)
at com.intellij.openapi.application.impl.ApplicationImpl$1.run(ApplicationImpl.java:238)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)

0
Comment actions Permalink

Creating UI in `SwissAsConfig.createComponent` should solve the problem:

public JComponent createComponent() {
if (configPanel == null) configPanel = new ...;
return configPanel.getMainPanel()
}

See also `UnnamedConfigurable.reset` method, that can be used instead of 'SwissAsConfig.updateUIState'.

0
Comment actions Permalink

I did what you proposed and override the reset method to include the code that was in the updateUIState and now I don't have any exception anymore ;)

 

Thanks a lot.

I can continue to work on the feature I was working on :) 

 

0
Comment actions Permalink

I've just run into a similar problem, trying to create a LanguageTextField.

I'm confused about why I should use createComponents() instead of createUIComponents(). What good is the createUIComponents() method if it isn't called on the Swing event dispatch thread?

Also, as I'm trying to use the UI designer, I have the field I want to create defined like this:


Doesn't declaring the field like this in the form editor mean that the generated code expects this component to be created in the createUIComponents() method?

PS: I'd love to know if there's a way to see the code generated when my own source code (in this case in Kotlin, not Java) is combined with the form info.

0

Please sign in to leave a comment.