Программно запустить событие выбора RCP - PullRequest
22 голосов
/ 01 февраля 2012

В моем приложении Eclipse RCP я использую Службу выбора, как описано в этой хорошей статье . Существует TreeViewer в одном представлении, зарегистрированном как SelectionProvider :

getSite().setSelectionProvider(viewer);

Другое представление получает события от TreeViewer :

selectionListener = new ISelectionListener() {
  public void selectionChanged(IWorkbenchPart part, ISelection selection) {
    pageSelectionChanged(part, selection);
  }
 };
 getSite().getPage().addSelectionListener(selectionListener);

Все работает нормально, если события запускаются моими обычными щелчками мыши. Я хотел бы программно запустить события выбора, выделив элемент в дереве:

treeViewer.setSelection(new StructuredSelection(element),true);

Это не работает. Метод selectionChanged не вызывается в представлении приемника. Проблема обсуждается в этой ветке форума . Нет решения.

РЕДАКТИРОВАТЬ

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

Мое решение состоит в том, чтобы зарегистрировать второе представление таким же образом на Selection Service, что и первое представление. После этого оба вида получают события выбора непосредственно из активного редактора.

Ответы [ 7 ]

26 голосов
/ 13 сентября 2012

Вы можете сделать две вещи:

1) сделайте выбор, а затем вызовите уведомляющих слушателей для SWT.SELECTION, т.е.:

mybutton.setSelection(true);
mybutton.notifyListeners(SWT.Selection, new Event());

Метод notifyListener предназначен для использования в пользовательских элементах управления, поэтому для большей корректности вы можете использовать параметр номер 2.

2) вызовите метод, который вы вызываете в своем слушателе, т. Е .:

this.myButton.addSelectionListener(new SelectionListener() {
    public void widgetSelected(final SelectionEvent e) {
      doSomethingaboutTheSelMethod();
 }

В этом случае вы можете позвонить:

doSomethingaboutTheSelMethod();
6 голосов
/ 10 мая 2012

Я только что столкнулся с этой проблемой и решил ее так:

treeViewer.getControl.setFocus();
treeViewer.setSelection(new StructuredSelection(element),true);

Задание фокуса на дереве перед выбором, казалось, уведомляет слушателей, где раньше этого не было.

2 голосов
/ 23 августа 2012

У меня была такая же проблема.Обходной путь, который я использовал, состоял в том, чтобы вызвать событие на программном союзнике Слушателя после вызова метода treeViewer.getTree().select(treeViewer.getTree().getItem(0));.

  1. Запросить слушателей, зарегистрированных в Дереве, и получить ссылку на вашего слушателя:

    org.eclipse.swt.widgets.Listener[] listeners = treeViewer.getTree().getListeners(SWT.Selection);
    for (int i=0; i<listeners.length; i++) {
            if (listeners[i] instanceof TypedListener) {
                if (((TypedListener)listeners[i]).getEventListener() instanceof TreeSelectionListener){
                      // Step 2: Fire the event code goes here
     }}}
    
  2. Создание SelectionEvent и запуск выбора путем ручного вызова метода widgetSelected :

    Event underlyingEvent = new Event();
    underlyingEvent.widget = treeViewer.getTree();
    SelectionEvent selectionEvent = new SelectionEvent(underlyingEvent);
    ((TreeSelectionListener)((TypedListener)listeners[i]).getEventListener()).widgetSelected(selectionEvent);
    

Это решение отлично сработало для меня.Надеюсь, это поможет вам.

1 голос
/ 02 апреля 2016

Убедитесь, что ваша часть (вид) имеет фокус! В противном случае setSelection не будет работать.

Сначала Inject PartService в вашем классе или добавьте его в качестве параметра в метод выполнения вашей команды (EPartService partService), затем выполните следующее:

MPart myPart = partService.findPart(MyPart.ID);
partService.activate(myPart, true);
treeViewer.getControl().setFocus();
treeViewer.setSelection(new StructuredSelection(myObject), true);
1 голос
/ 21 февраля 2012

StructuredViewer.setSelection(ISelection, boolean) сработает SelectionChangedEvent, если:

  • программа просмотра выполняет код, который явно сохраняет выделение (например, обновление), или
  • , исключение происходит до того, как оно попадает в событиеуведомление (например, когда вы звоните setSelection из потока не-пользовательского интерфейса, который выбрасывает Неверный доступ к потоку ).
1 голос
/ 03 февраля 2012

Попробуйте addPostSelectionListener вместо addSelectionListener, чтобы зарегистрировать слушателя на странице рабочей среды. Глядя на код StructuredViewer, упомянутый метод firePostSelectionChanged будет вызываться при программной настройке выбора.

1 голос
/ 02 февраля 2012

Попробуйте сделать

treeViewer.fireSelectionChanged();

или

treeViewer.firePostSelectionChanged();

после настройки выбора.


EDIT

Хорошо, поэтому вышеприведенные вызовы не работают ... Если вы достаточно отчаялись, вы можете отследить источники и выяснить, что на самом деле вызывает selectionChanged(). Просто установите точку останова в вашем методе и поднимите стек. Может быть, вы получите представление о том, как выполнить этот вызов по-другому.

...