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

4 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

Please sign in to leave a comment.