Get VirtualFile of selected text editor from a non-UI thread

Hi,

I'm quite new to intellij plugin development.

I am trying to get the selected file like this:

RobotFileManager.java: 110 | Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
RobotFileManager.java: 111 | VirtualFile virtualFile = FileDocumentManager.getInstance().getFile(editor.getDocument());


But I am getting the following exception :


Access is allowed from event dispatch thread only.
Details: Current thread: Thread[JobScheduler FJ pool 0/4,6,main] 1479683740
Our dispatch thread:Thread[AWT-EventQueue-1 13.1.4#IU-135.1230, eap:false,6,main] 733847011
SystemEventQueueThread: Thread[AWT-EventQueue-1 13.1.4#IU-135.1230, eap:false,6,main] 733847011
java.lang.Throwable
 at com.intellij.openapi.diagnostic.Logger.error(Logger.java:124)
 at com.intellij.openapi.application.impl.ApplicationImpl.a(ApplicationImpl.java:1086)
 at com.intellij.openapi.application.impl.ApplicationImpl.assertIsDispatchThread(ApplicationImpl.java:1074)
 at com.intellij.openapi.wm.impl.FocusManagerImpl.p(FocusManagerImpl.java:1163)
 at com.intellij.openapi.wm.impl.FocusManagerImpl.getFocusOwner(FocusManagerImpl.java:891)
 at com.intellij.openapi.wm.impl.IdeFocusManagerImpl.getFocusOwner(IdeFocusManagerImpl.java:119)
 at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl$2.run(FileEditorManagerImpl.java:202)
 at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl.a(FileEditorManagerImpl.java:230)
 at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl.getSplitters(FileEditorManagerImpl.java:1180)
 at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl.getSelectedTextEditor(FileEditorManagerImpl.java:1127)
 at com.millennialmedia.intellibot.psi.ref.RobotFileManager.findFile(RobotFileManager.java:110)
 at com.millennialmedia.intellibot.psi.ref.RobotFileManager.findGlobalFile(RobotFileManager.java:89)
 at com.millennialmedia.intellibot.psi.ref.RobotFileManager.findRobot(RobotFileManager.java:46)
 at com.millennialmedia.intellibot.psi.ref.RobotArgumentReference.resolveResource(RobotArgumentReference.java:181)
 at com.millennialmedia.intellibot.psi.ref.RobotArgumentReference.resolve(RobotArgumentReference.java:44)
 at com.intellij.codeInsight.TargetElementUtilBase.getReferenceOrReferencedElement(TargetElementUtilBase.java:315)
 at com.intellij.codeInsight.TargetElementUtil.getReferenceOrReferencedElement(TargetElementUtil.java:95)
 at com.intellij.codeInsight.TargetElementUtilBase.findTargetElement(TargetElementUtilBase.java:200)
 at com.intellij.codeInsight.TargetElementUtil.findTargetElement(TargetElementUtil.java:60)
 at com.intellij.codeInsight.daemon.impl.IdentifierHighlighterPass.doCollectInformation(IdentifierHighlighterPass.java:87)
 at com.intellij.codeHighlighting.TextEditorHighlightingPass.collectInformation(TextEditorHighlightingPass.java:62)
 at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass$1$1.run(PassExecutorService.java:380)
 at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1154)
 at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass$1.run(PassExecutorService.java:371)
 at com.intellij.openapi.progress.ProgressManager.executeProcessUnderProgress(ProgressManager.java:209)
 at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:212)
 at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.a(PassExecutorService.java:368)
 at com.intellij.codeInsight.daemon.impl.PassExecutorService$ScheduledPass.run(PassExecutorService.java:344)
 at com.intellij.concurrency.JobLauncherImpl$VoidForkJoinTask.exec(JobLauncherImpl.java:193)
 at jsr166e.ForkJoinTask.doExec(ForkJoinTask.java:260)
 at jsr166e.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:858)
 at jsr166e.ForkJoinPool.scan(ForkJoinPool.java:1687)
 at jsr166e.ForkJoinPool.runWorker(ForkJoinPool.java:1642)
 at jsr166e.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:109)


I can't find how to fix this...

It is possible that I am following a totally wrong aproach ?

Thanks!
0

Hi, thanks for that.. I had actually read that page, but somehow missed the threading rules.

My problem now is that I have to get a return value from that thread that will be invoked by

ApplicationManager.getApplication().invokeLater();

Also, a relevant question:
If I use invokeAndWait() instead, the editor will not be blocked right ?

0

Why do you need to use ApplicationManager.getApplication().invokeLater()?
Are your plugin sources available somewhere?

0

Yes, I'm trying to fix this issue:

https://github.com/millennialmedia/intellibot/issues/70#issuecomment-56791748

The patch is not working for non-UI threads.

0

The root problem of why it needs the ApplicationManager.getApplication().invokeLater()

is the way it's getting the path of the selected file that's active on the editor.
Which is:

FileEditorManager.getInstance(project).getSelectedTextEditor().getDocument()

Is there another way to get that path ?
0

I'll have to checkout the full sources to understand the context properly.

But it seems to me you're trying to "simulate" resolving of a reference in text by just passing in "String" and current project and trying to find the (relative) context via the active editor? Is this correct? If yes, this should be done completely different.

0

Yes that is correct.

I am more than open to suggestions :)

0

You'll want to use PsiReference here. They'll allow to compute resolve targets, completion etc. in a context (element-) dependent way. See https://confluence.jetbrains.com/display/IDEADEV/Developing+Custom+Language+Plugins+for+IntelliJ+IDEA#DevelopingCustomLanguagePluginsforIntelliJIDEA-ReferencesandResolve there's plenty of real world examples in IntelliJ Community source code.

0

请先登录再写评论。