Popup error on Linux

Hi ! is there something wrong with this call?

NavigationUtil.getPsiElementPopup(_psiElements, new DefaultPsiElementCellRenderer(), title).showInBestPositionFor(editor);

well, maybe not wrong, but something that I should know and take into account before executing that.


Because it's working fine in Windows, but not in Linux (Ubuntu 11.10 with phpstorm 4).

I don't have too much information about the error because is not my computer, but maybe you can guess what could be happening, or what should I check/do to make it safer.
This is the backtrace from the IDE:

------------------------------

Access is allowed from event dispatch thread only.

Details: Current thread: Thread[ApplicationImpl pooled thread 11,4,Idea Thread Group] 1843150554

Our dispatch thread:Thread[AWT-EventQueue-1 4.0.1#PS-117.257, eap:false,6,Idea Thread Group] 314598317

SystemEventQueueThread: Thread[AWT-EventQueue-1 4.0.1#PS-117.257, eap:false,6,Idea Thread Group] 314598317

java.lang.Throwable

at com.intellij.openapi.diagnostic.Logger.error(Logger.java:61)

at com.intellij.openapi.application.impl.ApplicationImpl.b(ApplicationImpl.java:989)

at com.intellij.openapi.application.impl.ApplicationImpl.assertIsDispatchThread(ApplicationImpl.java:973)

at com.intellij.openapi.wm.impl.FocusManagerImpl.p(FocusManagerImpl.java:1126)

at com.intellij.openapi.wm.impl.FocusManagerImpl.getFocusOwner(FocusManagerImpl.java:853)

at com.intellij.openapi.wm.impl.IdeFocusManagerImpl.getFocusOwner(IdeFocusManagerImpl.java:109)

at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl$2.run(FileEditorManagerImpl.java:191)

at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl.a(FileEditorManagerImpl.java:219)

at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl.getSplitters(FileEditorManagerImpl.java:1069)

at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl.c(FileEditorManagerImpl.java:1142)

at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl.getEditors(FileEditorManagerImpl.java:1115)

at com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl.isFileOpen(FileEditorManagerImpl.java:1035)

at com.intellij.ui.tabs.FileColorManagerImpl.getRendererBackground(FileColorManagerImpl.java:186)

at com.intellij.ide.util.PsiElementListCellRenderer$LeftRenderer.customizeCellRenderer(PsiElementListCellRenderer.java:94)

at com.intellij.ui.ColoredListCellRenderer.getListCellRendererComponent(ColoredListCellRenderer.java:72)

at com.intellij.ide.util.PsiElementListCellRenderer.getListCellRendererComponent(PsiElementListCellRenderer.java:149)

at javax.swing.plaf.basic.BasicListUI.updateLayoutState(BasicListUI.java:1344)

at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.java:1294)

at javax.swing.plaf.basic.BasicListUI$Handler.valueChanged(BasicListUI.java:2611)

at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:167)

at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:147)

at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:194)

at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:388)

at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:398)

at javax.swing.DefaultListSelectionModel.setSelectionInterval(DefaultListSelectionModel.java:442)
at javax.swing.JList.setSelectedIndex(JList.java:2179)
at com.intellij.openapi.ui.popup.PopupChooserBuilder.createPopup(PopupChooserBuilder.java:199)
at com.intellij.codeInsight.navigation.NavigationUtil.getPsiElementPopup(NavigationUtil.java:101)
at com.intellij.codeInsight.navigation.NavigationUtil.getPsiElementPopup(NavigationUtil.java:69)
at com.intellij.codeInsight.navigation.NavigationUtil.getPsiElementPopup(NavigationUtil.java:56)
  at com.magic.extensions.MagicGotoDeclarationHandler.getGotoDeclarationTargets(MagicGotoDeclarationHandler.java:141 )     // this is my class  
  at com.magic.extensions.MagicGotoDeclarationHandler.getGotoDeclarationTargets(MagicGotoDeclarationHandler.java:53)
at com.intellij.codeInsight.navigation.actions.GotoDeclarationAction.findTargetElementsNoVS(GotoDeclarationAction.java:198)
at com.intellij.codeInsight.navigation.CtrlMouseHandler.a(CtrlMouseHandler.java:392)
at com.intellij.codeInsight.navigation.CtrlMouseHandler.access$1500(CtrlMouseHandler.java:82)
at com.intellij.codeInsight.navigation.CtrlMouseHandler$TooltipProvider.a(CtrlMouseHandler.java:534)
at com.intellij.codeInsight.navigation.CtrlMouseHandler$TooltipProvider.access$1400(CtrlMouseHandler.java:482)
at com.intellij.codeInsight.navigation.CtrlMouseHandler$TooltipProvider$1$1.run(CtrlMouseHandler.java:524)
at com.intellij.openapi.application.impl.ApplicationImpl.runReadAction(ApplicationImpl.java:864)
at com.intellij.openapi.progress.util.ProgressIndicatorUtils$3.run(ProgressIndicatorUtils.java:60)
at com.intellij.openapi.progress.impl.ProgressManagerImpl$2.run(ProgressManagerImpl.java:178)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:218)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.runProcess(ProgressManagerImpl.java:169)
at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runWithWriteActionPriority(ProgressIndicatorUtils.java:55)
at com.intellij.codeInsight.navigation.CtrlMouseHandler$TooltipProvider$1.run(CtrlMouseHandler.java:522)
at com.intellij.openapi.application.impl.ApplicationImpl$6.run(ApplicationImpl.java:434)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
at com.intellij.openapi.application.impl.ApplicationImpl$1$1.run(ApplicationImpl.java:145)


------------------------------

I'm using that line inside a my custom GotoDeclarationHandler because when there are more than one PsiElement to be returned, if the sourceElement doesn't have a psiReference it fails when the IDE tries to create the popup (to choose the different psiElements), so I'm creating the popup by my own, with a custom title (I think the only reason for reading the reference from the sourceElement in the original code from the IDE is to get the title for the popup).

Thanks !!

8 comments
Comment actions Permalink

The error tells you exactly what is wrong:
"Access is allowed from event dispatch thread only."

0
Comment actions Permalink

Yes, but I don't know what it means, and I'm confused because in Windows it's working fine.
Please help me to solve or understand this problem Dimitry, I don't know what I'm doing wrong.

0
Comment actions Permalink

The problem is actually independent of the platform. The getGotoDeclarationTargets() method is not only used to perform the actual navigation, but also for other purposes (in this case, it's called from the code that is calculating the contents of the Ctrl-hover popup). Because of that, it's not appropriate to show any UI in an implementation of this method.

0
Comment actions Permalink

OK, but how can I solve my problem then?
Because the GotoDeclarationAction has this code:

public static boolean chooseAmbiguousTarget(final Editor editor,
                                              int offset,
                                              PsiElementProcessor<PsiElement> processor,
                                              String titlePattern,
                                              PsiElement[] elements) {
    if (TargetElementUtilBase.inVirtualSpace(editor, offset)) {
      return false;
    }

    final PsiReference reference = TargetElementUtilBase.findReference(editor, offset);        // I'm getting null here

    if (elements == null || elements.length == 0) {
      final Collection<PsiElement> candidates = suggestCandidates(reference);
      elements = PsiUtilCore.toPsiElementArray(candidates);
    }

    if (elements.length == 1) {
      PsiElement element = elements[0];
      LOG.assertTrue(element != null);
      processor.execute(element);
      return true;
    }
    if (elements.length > 1) {
      final TextRange range = reference.getRangeInElement();                                 // the IDE is not checking for null here !!
      final String refText = range.substring(reference.getElement().getText());              // neither here
      String title = MessageFormat.format(titlePattern, refText);
      NavigationUtil.getPsiElementPopup(elements, new DefaultPsiElementCellRenderer(), title, processor).showInBestPositionFor(editor);
      return true;
    }
    return false;
  }



I've tried adding an extension point to "psi.referenceContributor" but that code is executed too often, that's why I choose the GotoDeclarationHandler, I want to add options to that part only (at really to GotoDeclarationAction only).

Do you know a better solution for this?
and if not, do you know how to check if it's safe to show the popup?

Thanks !!

0
Comment actions Permalink

IntelliJ IDEA 12 does have a null check in this code. Generally, psi.referenceContributor is the correct way to implement such behavior, as it lets you support many other features beyond goto definition (completion, find usages, rename etc.).

0
Comment actions Permalink

The problem is that the psiReference extension point is executed too often, and I need to run very slow code, but I only need to do that when an GotoDeclarationAction is executed, can I check for that? in the psiReference or in the GotoDeclarationHandler.

0
Comment actions Permalink

The correct solution is to cache the results of your very slow calculation.

0
Comment actions Permalink

I'm caching it, but if the user changes some xml file (and this happens very often too!) I need to calculate the gotodeclaration again (and sometimes I need to run PHP code for getting the right result !)

PS: I think would be a good idea to have extensions points for every action, so if we want add some functionality to an existent and specific action we just go for it, receive the original event, and decide if the default action should execute too or stop after our custom action.

0

Please sign in to leave a comment.