structure view refresh

Hi, As I am doing my own non-PSI based structured view, I am having to write code to notify the structured view when the associated editor is changed. Basically, I add a document listener which then triggers a rebuild() on the structured view.

1. Is the following code the proper way to notify the structured view that the associated editor data has changed? seems like a hack.

 
final StructureViewWrapper viewWrapper =
   
StructureViewFactoryEx.getInstanceEx(project).getStructureViewWrapper();
if (
viewWrapper instanceof StructureViewWrapperImpl ) {
   
ApplicationManager.getApplication().invokeLater(
      new
Runnable() {
         @Override
         public void
run() {
            ((
StructureViewWrapperImpl) viewWrapper).rebuild();
         }
      });
}


2. The structured view flashes like crazy on every keystroke. Do I have to manually insert my own delay to avoid such frequent updates (and check to make sure multiple change events don't force multiple updates during the same delay period)?

thanks! I've *almost* got the structured view working with ANTLR parse trees. I'm just trying to link the editor and the structure view. been reading source code for hours now.

Thanks in advance,
Terence

0
4 comments

From a quick look you shouldn't need to do this (see timerListener in CTOR), please try to debug into com.intellij.ide.impl.StructureViewWrapperImpl#checkUpdate

0

ah! I was so busy debugging checkUpdate that I missed the timerListener in the ctor. I just couldn't figure out where in the heck it was doing a timer or similar. hahaha. thanks a million Yann!
Terence

0

oh by "shouldn't need to do this" you mean forcing the refresh? Hmm...I get no changes unless i kick it manually.  See my listener here. In my builder i ask my project component to register the listener. It does seem like the code wants to update the tree but debugging StructureViewWrapperImpl skips scheduleRebuild() because my StructureViewTreeElement's getValue() is never null.

  private void setFile(VirtualFile file) {
    boolean forceRebuild = !Comparing.equal(file, myFile);
    if (!forceRebuild && myStructureView != null) {
      StructureViewModel model = myStructureView.getTreeModel();
      StructureViewTreeElement treeElement = model.getRoot();
      Object value = treeElement.getValue();
      if (value == null || value instanceof PsiElement && !((PsiElement)value).isValid()) { <----- I always fail this condition.
        forceRebuild = true;
      }
    }
    if (forceRebuild) {
      myFile = file;
      scheduleRebuild();
    }
  }

As I don't use PsiElement's I don't have a way to say !isValid().  Should I be returning null from getValue()?

My code looks like:

public class STGroupStructureViewTreeElement
   implements StructureViewTreeElement, ItemPresentation
{
   protected ParseTree node;
@Override
public Object getValue() {
   return node;
}...


Should I fake a PsiElement that is always valid? Not sure I can build one of them manually if I recall.

thanks!
Terence

0

ah ha! Solved it. I need to have getValue() return null from the *root* tree element and whole tree is invalidated. Woot!

0

Please sign in to leave a comment.