0

I'm working on an Eclipse RCP application and I'm trying to update an expression value which is provided by MySourceProvider according to selection changes on a TableViewer in MyEditorPart.

MyEditorPart instance defines a TableViewer like this:

public class MyEditorPart extends EditorPart {  

@Override
public void createPartControl(Composite parent) {  

  TableViewer tableviewer = new TableViewer(parent, SWT.CHECK);
  tableviewer.setContentProvider(ArrayContentProvider.getInstance());
  getSite().setSelectionProvider(tableViewer);  

...

MySourceProvider have some expression values like this:

public class MySourceProvider extends AbstractSourceProvider {

public static final String EXPR = "org.xyz.isEntrySelected";
// other expressions

@Override
public String[] getProvidedSourceNames() {
  return new String[] { EXPR,
  // other expressions
  };
}

@Override
public Map getCurrentState() {
  HashMap<String, Object> map = new HashMap<String, Object>(1);
  map.put(EXPR, expr_value); // expr_value calculated by the listener
  // other expressions
  return map;
}

I want to change expr_value according to selection changes on TableViewer. I registered the listener like this:

window.getSelectionService().addPostSelectionListener(MyEditorPartId, selectionListener);  
private final ISelectionListener selectionListener = new  SelectionListener() {
    @Override
    public void selectionChanged(IWorkbenchPart part, ISelection selection) {
        handleEvent();
    }
};

The listener registers successfully but gets notified only once if I clicked somewhere on MyEditorPart (not just TableViewer but the whole editor). To get notified again, I have to click on some other view (or editor) part to lose focus and then click again on MyEditorPart.

1. Why does the listener gets notified only once when MyEditorPart re-gains focus?
2. How to listen only to selection changes to TableViewer rows?

What am I missing here? What is the proper way to listen to selection changes?

Thanks in advance.

emrekgn
  • 624
  • 9
  • 25

2 Answers2

1

What you need is not a SelectionListener, but a SelectionChangedListener.

With this you can write the following code:

viewer.addSelectionChangedListener(new ISelectionChangedListener() {
  @Override
  public void selectionChanged(SelectionChangedEvent event) {
    IStructuredSelection selection = viewer.getStructuredSelection();
    Object firstElement = selection.getFirstElement();
    // do something with it
  }
}); 
Gergely Bacso
  • 14,243
  • 2
  • 44
  • 64
  • I understand but I have to create the listener on another class `MySourceProvider`, that is why I'm trying to use `getSelectionService().addPostSelectionListener()` and this method only accepts `ISelectionListener`? Instead of this, should I use your solution with an EventBroker to notify `MySourceProvider`? – emrekgn Nov 05 '15 at 08:13
  • What you need is likely a simple callback function. Try to avoid overcomplicating things with JFace tricks. If the action you want to respond to is "user selecting an item in a table", then the JFace listener you need is selectionChangedListener. From that on, the rest is just sharing references and calling methods you wrote. – Gergely Bacso Nov 05 '15 at 08:18
0

It does appear that this form of addPostSelectionListener only fires when the part becomes active. Use the:

addPostSelectionListener(ISelectionListener listener)

form of the listener which is called for every selection change.

You can then test the IWorkbenchPart id in the listener:

@Override
public void selectionChanged(final IWorkbenchPart part, final ISelection selection)
{
  if (MyEditorPartId.equals(part.getSite().getId()))
   {
     // your code
   }
}
greg-449
  • 109,219
  • 232
  • 102
  • 145
  • I've tried it but unfortunately it has the same problem, it only fires once. Forgive my silly question but examples I found, always use this listener - selectionprovider mechanism from a `ViewPart`, I wonder if it has something to do with using a `EditorPart`? Because I've some `ViewPart` classes that uses this mechanism and they just work fine. – emrekgn Nov 05 '15 at 17:13