以编程方式触发RCP选择事件

时间:2012-02-01 19:33:39

标签: java eclipse-rcp jface

在我的Eclipse RCP应用程序中,我使用了这个不错的article中描述的Selection Service。注册为 SelectionProvider 的一个视图中有 TreeViewer

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 未在receiver-view中调用。这个问题在forum thread中进行了讨论。没有解决方案。

编辑

没有正确的方法来处理鼠标触发点击的方式与编程选择相同。单击鼠标可激活视图,而编程选择则不会。

我的解决方案是以Selection Service作为第一个视图以相同的方式注册第二个视图。之后,两个视图都直接从活动编辑器中获取选择事件。

7 个答案:

答案 0 :(得分:25)

你可以做两件事:

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

答案 1 :(得分:6)

我刚遇到这个问题并解决了这个问题:

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

在做出选择之前将焦点放在树上似乎会通知听众,而不是之前。

答案 2 :(得分:2)

我遇到了同样的问题。我使用的解决方法是在调用treeViewer.getTree().select(treeViewer.getTree().getItem(0));方法后以编程方式触发侦听器上的事件。

  1. 查询在Tree上注册的侦听器并获取对侦听器的引用:

    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);
    
  3. 这个解决方案对我来说很好。希望它能为你做到。

答案 3 :(得分:1)

尝试做

treeViewer.fireSelectionChanged();

treeViewer.firePostSelectionChanged();
设置选择后


修改

好的,所以上面的调用不起作用......如果你非常绝望,你可以追踪来源并找出实际调用selectionChanged()的内容。只需在方法中设置一个断点并启动堆栈。也许你会想到如何以另一种方式实现这个调用。

答案 4 :(得分:1)

尝试使用addPostSelectionListener代替addSelectionListener在工作台页面注册您的侦听器。查看StructuredViewer的代码,将以编程方式设置选择时调用上述方法firePostSelectionChanged

答案 5 :(得分:1)

StructuredViewer.setSelection(ISelection, boolean)会触发SelectionChangedEvent,除非:

  • 查看器正在执行明确保留选择的代码(如刷新)或
  • 在发生事件通知之前发生异常(例如,当您从非UI线程调用setSelection时会抛出无效的线程访问)。

答案 6 :(得分:1)

确保您的声部(视图)具有焦点!否则setSelection将无效。

首先Inject您的类中的PartService,或将其作为参数添加到命令执行方法(EPartService partService)中,然后执行以下操作:

MPart myPart = partService.findPart(MyPart.ID);
partService.activate(myPart, true);
treeViewer.getControl().setFocus();
treeViewer.setSelection(new StructuredSelection(myObject), true);