javaswtjfacetreeviewer

JFace TreeViewer expand or collapse on selection


I've implemented a selection listener for my treeviewer to expand or collapse a node on selection. This impementation works fine for collapsing, but does not expand a node.

this.getTree().addListener(SWT.Selection, new Listener() {
        @Override
        public void handleEvent(Event event) {
            TreeItem treeItem = (TreeItem) event.item;
            if (treeItem.getItems().length > 0) {
                if (MyTreeViewer.this.getExpandedState(treeItem)) {
                    MyTreeViewer.this.collapseToLevel(treeItem, MyTreeViewer.this.ALL_LEVELS);
                } else {
                    MyTreeViewer.this.expandToLevel(treeItem, 1);
                }
                MyTreeViewer.this.refresh();
            }
        }
    });

Do you have any suggestions how to fix this?


Solution

  • For a JFace TreeViewer you should use a ISelectionChangedListener or a IDoubleClickListener - do not use the underlying Tree listeners as they may not interact correctly with the viewer.

    This is what I use for double click:

    public class TreeDoubleClickListener implements IDoubleClickListener
    {
      @Override
      public void doubleClick(final DoubleClickEvent event)
      {
        IStructuredSelection selection = (IStructuredSelection)event.getSelection();
        if (selection == null || selection.isEmpty())
          return;
    
        Object sel = selection.getFirstElement();
    
        TreeViewer treeViewer = (TreeViewer)event.getViewer();
    
        IContentProvider provider = treeViewer.getContentProvider();
    
        if (provider instanceof ITreeContentProvider)
         {
           ITreeContentProvider treeProvider = (ITreeContentProvider)provider;
    
           if (!treeProvider.hasChildren(sel))
             return;
    
           if (treeViewer.getExpandedState(sel))
             treeViewer.collapseToLevel(sel, AbstractTreeViewer.ALL_LEVELS);
           else
             treeViewer.expandToLevel(sel, 1);
         }
      }
    }
    

    The key thing here is to use the selection as the argument to collapseToLevel / expandToLevel.

    Just change to implement ISelectionChangedListener to work on selection.

    Add the listener with TreeViewer addDoubleClickListener or addSelectionChangedListener