如何在一个视图中设置两个选择提供程序

时间:2016-12-05 13:05:13

标签: eclipse-plugin eclipse-rcp rcp treeviewer

我有一个视图,我有两个树查看器。在createPartControl()我可以为两个视图设置selectionProviders。它需要其中一个。

这是我的代码段。 查看代码:

IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
IWorkbenchPartSite activePartSite = workbenchWindow.getActivePage().getActivePart().getSite();
activePartSite.setSelectionProvider(inputTreeViewer);
activePartSite.setSelectionProvider(compositeTreeViewer);

// Here the last line the selection provider code for the top one. 
// Hence I only get selections from the second tree. 

我们如何解决问题?我尝试从ISelectionProvider继承视图类并覆盖getSelection()方法。但这没有任何帮助。

有人可以提出建议吗?

2 个答案:

答案 0 :(得分:1)

我建议为每个树添加一个焦点监听器,并使用当前聚焦的树查看器调用partSite.setSelectionProvider()。例如:

treeViewer1.getTree().addListener( SWT.FocusIn, event -> site.setSelectionProvider( treeViewer1 ) );
treeViewer2.getTree().addListener( SWT.FocusIn, event -> site.setSelectionProvider( treeViewer2 ) );

我将它作为练习留给读者去除听众复制。

或者,您可以创建代理选择提供程序,以侦听两个树查看器中的选择更改并传播最新的选择。这些方面的东西:

public class ProxySelectionProvider implements ISelectionProvider {

  private ISelection selection;
  private final Collection<ISelectionChangedListener> listeners;

  public ProxySelectionProvider( StructuredViewer...  viewers ) {
    listeners = new ArrayList<>();
    selection = StructuredSelection.EMPTY;
    for( StructuredViewer viewer : viewers ) {
      ISelectionChangedListener selectionListener = this::selectionChanged;
      viewer.addSelectionChangedListener( selectionListener );
      viewer.getControl().addDisposeListener( event -> viewer.removeSelectionChangedListener( selectionListener ) );
    }
  }

  @Override
  public void addSelectionChangedListener( ISelectionChangedListener listener ) {
    listeners.add( listener );
  }

  @Override
  public void removeSelectionChangedListener( ISelectionChangedListener listener ) {
    listeners.remove( listener );
  }

  @Override
  public ISelection getSelection() {
    return selection;
  }

  @Override
  public void setSelection( ISelection selection ) {
    this.selection = selection;
  }

  private void selectionChanged( SelectionChangedEvent event ) {
    selection = event.getSelection();
    notifyListeners();
  }

  private void notifyListeners() {
    SelectionChangedEvent event = new SelectionChangedEvent( this, selection );
    new ArrayList<>( listeners ).forEach( listener -> listener.selectionChanged( event ) );
  }
}

使用这样的选择提供者:

ISelectionProvider selectionProvider = new ProxySelectionProvider( treeViewer1, treeViewer2 );
IWorkbenchPartSite partSite = workbenchWindow.getActivePage().getActivePart().getSite();
partSite.setSelectionProvider( selectionProvider );

答案 1 :(得分:-1)

我使用这种方法解决了这个问题。

public class SelectionProviderAdapater implements IPostSelectionProvider {
    public class InternalListener implements ISelectionChangedListener, FocusListener {
        @Override
        public void focusGained(FocusEvent e) {
            doFocusChanged(e.widget);
        }

        @Override
        public void focusLost(FocusEvent e) {
        }

        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            doSelectionChanged(event);
        }
    }

    /**
     * The array of viewers.
     */
    private StructuredViewer[] viewers;

    /**
     * The current viewer in focus.
     */
    private StructuredViewer viewerInFocus;

    /**
     * The list of selection changed listeners.
     */
    private final ListenerList selectionChangedListeners = new ListenerList();

    /**
     * The list of post selection changed listeners.
     */
    private final ListenerList postSelectionChangedListeners = new ListenerList();

    /**
     * The internal listener instance.
     */
    private final InternalListener internalListener = new InternalListener();

    /**
     * The internal post selection listener instance.
     */
    private final ISelectionChangedListener internalPostSelectionListener = new ISelectionChangedListener() {
        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            doPostSelectionChanged(event);
        }
    };

    @Override
    public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
        postSelectionChangedListeners.add(listener);
    }

    @Override
    public void addSelectionChangedListener(ISelectionChangedListener listener) {
        selectionChangedListeners.add(listener);
    }

    /**
     * Sets the viewer in focus and fires selection change events.
     *
     * @param control
     *            The {@link Widget} that has gained focus.
     */
    private void doFocusChanged(Widget control) {
        for (StructuredViewer viewer : viewers) {
            if (viewer.getControl() == control) {
                propagateFocusChanged(viewer);
                return;
            }
        }
    }

    /**
     * Fires post selection changed events if the {@link SelectionChangedEvent}
     * 's selection provider is the current viewer in focus.
     *
     * @param event
     *            The selection changed event.
     */
    private void doPostSelectionChanged(SelectionChangedEvent event) {
        ISelectionProvider provider = event.getSelectionProvider();
        if (provider == viewerInFocus) {
            firePostSelectionChanged();
        }
    }

    /**
     * Fires selection changed events if the {@link SelectionChangedEvent}'s
     * selection provider is the current viewer in focus.
     *
     * @param event
     *            The selection changed event.
     */
    private void doSelectionChanged(SelectionChangedEvent event) {
        ISelectionProvider provider = event.getSelectionProvider();
        if (provider == viewerInFocus) {
            fireSelectionChanged();
        }
    }

    /**
     * Notifies post selection changed listeners of a selection changed event.
     */
    private void firePostSelectionChanged() {
        if (postSelectionChangedListeners != null) {
            SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());

            Object[] listeners = postSelectionChangedListeners.getListeners();
            for (Object listener : listeners) {
                ISelectionChangedListener selectionChangedListener = (ISelectionChangedListener) listener;
                selectionChangedListener.selectionChanged(event);
            }
        }
    }

    /**
     * Notifies selection changed listeners of a selection changed event.
     */
    private void fireSelectionChanged() {
        if (selectionChangedListeners != null) {
            SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());

            Object[] listeners = selectionChangedListeners.getListeners();
            for (Object listener : listeners) {
                ISelectionChangedListener selectionChangedListener = (ISelectionChangedListener) listener;
                selectionChangedListener.selectionChanged(event);
            }
        }
    }

    @Override
    public ISelection getSelection() {
        if (viewerInFocus != null) {
            return viewerInFocus.getSelection();
        }
        return StructuredSelection.EMPTY;
    }

    public StructuredViewer getViewerInFocus() {
        return viewerInFocus;
    }

    /**
     * Sets the viewer as the viewer in focus and fires selection changed
     * events.
     *
     * @param viewer
     *            The new viewer in focus.
     */
    private void propagateFocusChanged(StructuredViewer viewer) {
        if (viewer != viewerInFocus) {
            viewerInFocus = viewer;
            fireSelectionChanged();
            firePostSelectionChanged();
        }
    }

    @Override
    public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
        postSelectionChangedListeners.remove(listener);
    }

    @Override
    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
        selectionChangedListeners.remove(listener);
    }

    @Override
    public void setSelection(ISelection selection) {
        if (viewerInFocus != null) {
            viewerInFocus.setSelection(selection);
        }
    }

    /**
     * Sets the selection on the current viewer in focus.
     *
     * @param selection
     *            The selection to set.
     * @param reveal
     *            true if the selection is to be made visible, and false
     *            otherwise
     */
    public void setSelection(ISelection selection, boolean reveal) {
        if (viewerInFocus != null) {
            viewerInFocus.setSelection(selection, reveal);
        }
    }

    /**
     * Sets the collection of viewers to be monitored by this mediator.
     *
     * @param newViewers
     *            The collection of viewers.
     */
    public void setViewers(Collection<? extends StructuredViewer> newViewers) {
        // Remove listeners from any previous viewers.
        if (viewers != null) {
            for (StructuredViewer viewer : viewers) {
                viewer.removeSelectionChangedListener(internalListener);
                viewer.removePostSelectionChangedListener(internalPostSelectionListener);
                Control control = viewer.getControl();
                if (!control.isDisposed()) {
                    control.removeFocusListener(internalListener);
                }
            }
        }
        viewers = null;
        viewerInFocus = null;

        if (newViewers != null) {
            viewers = newViewers.toArray(new StructuredViewer[newViewers.size()]);
            for (StructuredViewer viewer : viewers) {
                viewer.addSelectionChangedListener(internalListener);
                viewer.addPostSelectionChangedListener(internalPostSelectionListener);
                Control control = viewer.getControl();
                control.addFocusListener(internalListener);
                if (control.isFocusControl()) {
                    propagateFocusChanged(viewer);
                }
            }
        }
    }
}

在你的视图中创建这个类的实例。使用setViewers()方法设置查看器,这些方法需要被选中。然后将其设置为选择提供者。它应该开始工作。