Programmatically Fire a RCP Selection Event
Asked Answered
C

7

25

In my Eclipse RCP application I use the Selection Service as described in this nice article. There is a TreeViewer in one view registered as a SelectionProvider:

getSite().setSelectionProvider(viewer);

Another view is receiving the events from the TreeViewer:

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

Everything works fine, if the events are triggered my normal mouse clicks. I would like to programmatically fire a selection events by selection an item in the tree:

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

This is not working. Method selectionChanged is not called in the receiver-view. The issue is discussed in this forum thread. There is no solution.

EDIT

There is no proper way to handle a mouse triggered click the same way as a programmatically selection. A mouse click activates the view a programmatically selection does not.

My Solution is to register the second view the same way by Selection Service as the first view. After that both view are getting selection events directly from the active editor.

Clement answered 1/2, 2012 at 19:33 Comment(4)
I remember to have faced the same problem. I have solved it by extracting all the code from the listener method and creating another public method from this code. So that listener method delegated the call to this new method. And in the place where you want to set selection I simply called that new method. Don't know whether it's doable/allowed in your environment/project.Buddy
I have two different views. I can't call methods from one view in the other view. That's why I use the selection service.Breadroot
You can get the reference to your view with: (YourView) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(YourView.ID);Buddy
you should consider validate an answer for your question. Regards.Jollanta
S
29

You can do two things:

1) do the selection and then call notify listeners for an SWT.SELECTION i.e. :

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

The notifyListener method is intented to be used for custom controls so to be more correct you could do option number 2.

2) call the method that you call in your listener i.e.:

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

In this case you can call:

doSomethingaboutTheSelMethod();
Slipshod answered 13/9, 2012 at 8:1 Comment(0)
C
6

I've just had this problem and solved it like this:

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

Giving the focus to the tree before making the selection seemed to notify the listeners, where before it was not.

Cadmann answered 10/5, 2012 at 15:15 Comment(1)
Yes it worked for me. Seems to be true for Inbuilt controls.Promotive
F
2

I had the same problem. The workaround I used was to trigger the event on the Listener programmatic-ally after calling the treeViewer.getTree().select(treeViewer.getTree().getItem(0)); method.

  1. Query the listeners registered on the Tree and get a reference to your listener:

    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. Create a SelectionEvent and trigger the selection by manually calling the widgetSelected method:

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

This solution worked fine for me. Hope it does for you.

Felicific answered 23/8, 2012 at 12:32 Comment(0)
P
1

Try to do a

treeViewer.fireSelectionChanged();

or

treeViewer.firePostSelectionChanged();

after setting the selection.


EDIT

Ok, so the above calls doesn't work... If you are desperate enough you could trace through the sources and find out what actually calls selectionChanged(). Just set a breakpoint in your method and get up the stack. Maybe you get an idea of how to achieve this call on another way.

Prognosticate answered 2/2, 2012 at 8:8 Comment(2)
Both methods are protected. I can create a subclass of TreeViewer to call them but that's dirty somehow...Breadroot
I created a subclass of TreeViewer to call the protected methods fireSelectionChanged and firePostSelectionChanged. No success. selectionChanged is not called in the view which should receive the events.Breadroot
A
1

Try addPostSelectionListener instead of addSelectionListener to register your listener at the workbench page. Looking at the code of StructuredViewer, the mentioned method firePostSelectionChanged will be called when programmatically setting the selection.

Adim answered 3/2, 2012 at 10:13 Comment(1)
I have tried both: adding a SelectionListener and a PostSelectionListener. No Success.Breadroot
D
1

StructuredViewer.setSelection(ISelection, boolean) will fire SelectionChangedEvent unless:

  • the viewer is executing code that explicitly preserves selection (like refresh) or
  • an exception occurs before it gets to event notification (e.g. when you call setSelection from a non-UI thread which throws Invalid thread access).
Dogwood answered 21/2, 2012 at 12:59 Comment(0)
P
1

Make sure your Part (view) has the focus! Otherwise setSelection won't work.

First Inject the PartService in your class, or add it as parameter in your command execute method (EPartService partService), then do the following:

MPart myPart = partService.findPart(MyPart.ID);
partService.activate(myPart, true);
treeViewer.getControl().setFocus();
treeViewer.setSelection(new StructuredSelection(myObject), true);
Pander answered 2/4, 2016 at 7:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.