Wednesday, February 18, 2009

Eclipse : How to Implement ISelectionProvider

ISelectionProvider interface provides a way to send selection events to the the ISelectionService which is received by all the ISelectionListener implementing views. All the JFace Structured viewers implements the ISelectionProvider and provide a StructuredSelection.

There are scenarios where we have a custom view which might want to fire a Selectionto the listeners. Let us look at how to do that.

Say you have a view with a Button and on clicking the button you want to send a selection event.



import org.eclipse.core.runtime.ListenerList;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;

public class ButtonView extends ViewPart implements ISelectionProvider {

private String selection;

ListenerList listeners = new ListenerList();

Button button = null;

@Override
public void createPartControl(Composite parent) {
parent.setLayout(new GridLayout(2, false));
button = new Button(parent, SWT.BORDER);
button.setText("Press Me");
getSite().setSelectionProvider(this);
button.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
setSelection(new StructuredSelection(button.getText()));
}
});
}

@Override
public void setFocus() {
}

public void addSelectionChangedListener(ISelectionChangedListener listener) {
listeners.add(listener);
}

public ISelection getSelection() {
return new StructuredSelection(selection);
}

public void removeSelectionChangedListener(
ISelectionChangedListener listener) {
listeners.remove(listener);
}

public void setSelection(ISelection select) {

Object[] list = listeners.getListeners();
for (int i = 0; i < list.length; i++) {
((ISelectionChangedListener) list[i])
.selectionChanged(new SelectionChangedEvent(this, select));
}
}

}




Now the ButtonView is implementing the ISelectionProvider and registered itself as a SelectionProvider to the workbench site. Now lets add the view to the views extension point. We will also create a ButtonListenerView which behaves as a SelectionListener by implementing ISelectionListener.



import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.part.ViewPart;

public class ButtonListenerView extends ViewPart implements ISelectionListener {

Button button;

@Override
public void createPartControl(Composite parent) {
getSite().getPage().addSelectionListener(this);
button = new Button(parent, SWT.BORDER);
button.setText("Before Selection Happened");
}

@Override
public void setFocus() {


}

public void selectionChanged(IWorkbenchPart part, ISelection selection) {
if (part instanceof ButtonView) {
String text = ((StructuredSelection) selection).getFirstElement()
.toString();
button.setText(text);
}
}

}




Now ButtonView sends the selection event to the selection service and the ButtonListenerView listens for the Selection events from the workbench. There is one more step to add the views to the views extension.


<extension
point="org.eclipse.ui.views">
<view
class="com.blog.sample.ui.ButtonView"
id="com.blog.sample.ui.ButtonView"
name="Button View"
restorable="true">
</view>
<view
class="com.blog.sample.ui.ButtonListenerView"
id="com.blog.sample.ui.ButtonListenerView"
name="Button Listener"
restorable="true">
</view>
</extension>



Lets see the screenshot before and after the button is clicked on the ButtonView.

Before the ButtonView send the ISelection,


Now clicking the Press Me button sends a selection event to all the listeners. ButtonListenerView processes the selection in the selectionChanged method.

No comments: