2016-12-05 21 views
1

У меня есть вид, где у меня есть два зрелища. В createPartControl() я могу установить selectionProviders для обоих видов. Он берет один из них.Как установить два поставщика выбора в одном виде

Вот мой фрагмент. The View Код:

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(). Но это не помогло.

Может кто-нибудь что-то предложить?

+0

Я вижу, что вы новичок в SO. Если вы чувствуете, что ответ решил проблему, отметьте ее как «принятую», нажав зеленую галочку. Это помогает сосредоточиться на старых постах, у которых до сих пор нет ответов. –

ответ

1

Я предлагаю добавить слушателя фокуса к каждому из деревьев и вызвать partSite.setSelectionProvider() с в настоящее время сфокусированным деревом. Например:

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

Я оставлю его как упражнение для чтения, чтобы удалить дублирование слушателя.

В качестве альтернативы вы можете создать провайдер выбора proxy, который прослушивает изменения выбора в обоих зрителях деревьев и распространяет самый последний выбор. Что-то вдоль этих линий:

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); 
+0

Метод addListener() принимает только int, Listener в качестве параметров. Как установить setProviders в качестве второго параметра. Ранее я пытался с treeviewer.getControl.addFocusLisnter(), но он не дал никакого результата. –

+0

Также я читал где-то setSelectionProvider() должен быть вызван в activesite внутри метода createPartControl(). Таким образом, вызывая его внутри прослушивателя фокуса, он не регистрирует его в качестве поставщика выбора. –

+0

Пример кода использует выражение лямбда, которое эквивалентно 'Listener :: handleEvent()'. Если 'setSelectionProvider()' нужно вызывать внутри 'createPartControl()', то вам нужно взять альтернативный подход и использовать службу выбора прокси. –

-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); 
       } 
      } 
     } 
    } 
} 

Создать экземпляр этого класса в ваших view.Set зрителей с помощью setViewers() метод, который нужно прислушиваются для selection.Then установить его в качестве выбора provider.It должен начать работать.