| <html> | |
| <head> | |
| <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252"> | |
| <title>Eclipse Workbench: Using the Selection Service</title> | |
| <link rel="stylesheet" href="../default_style.css"> | |
| </head> | |
| <body LINK="#0000ff" VLINK="#800080"> | |
| <div align="right"> <font face="Times New Roman, Times, serif" size="2">Copyright | |
| © 2006, 2008 Marc R. Hoffmann</font> | |
| <table border=0 cellspacing=0 cellpadding=2 width="100%"> | |
| <tr> | |
| <td align=LEFT valign=TOP colspan="2" bgcolor="#0080C0"><b><font face="Arial,Helvetica"><font color="#FFFFFF"> Eclipse | |
| Corner Article</font></font></b></td> | |
| </tr> | |
| </table> | |
| </div> | |
| <div align="left"> | |
| <h1><img src="images/Idea.jpg" height=86 width=120 align=CENTER></h1> | |
| </div> | |
| <p> </p> | |
| <h1 ALIGN="CENTER">Eclipse Workbench: Using the Selection Service</h1> | |
| <blockquote> | |
| <b>Summary</b> | |
| <br> | |
| The selection service provided by the Eclipse workbench allows efficient | |
| linking of different parts within the workbench window. Knowing and using the | |
| existing selection mechanisms gives your plug-ins a clean design, smoothly | |
| integrates them into the workbench and opens them for future extensions. | |
| <p><b>By Marc R. Hoffmann, Mountainminds GmbH & Co. KG, hoffmann@mountainminds.com</b><br> | |
| <font size="-1">April 14, 2006, last update August 28, 2008</font> | |
| </p> | |
| </blockquote> | |
| <hr width="100%"> | |
| <h2>Introduction</h2> | |
| <p> | |
| The Eclipse workbench is a powerful UI framework for IDEs and also other | |
| applications. It provides many services for a highly integrated and extensible | |
| user interfaces. One of the integration aspects are view parts that provide | |
| additional information for particular objects and update their content | |
| automatically whenever such objects are selected somewhere in the workbench | |
| window. For example the <i>"Properties"</i> view behaves in this way: Wherever | |
| an element is selected in the workbench this view lists the properties of | |
| that element. | |
| </p> | |
| <img src="images/screen1.gif" width="636" height="222" title="Screen 1"> | |
| <p> | |
| Other aspects of the workbench like the enablement of global actions may also | |
| depend on the current selection. | |
| </p> | |
| <p> | |
| Instead of implementing "hard-wired communication" plug-ins can rely on the so | |
| called <i>selection service</i>. It decouples parts where items can be | |
| selected from others reacting on selection changes. | |
| </p> | |
| <p> | |
| This article outlines the functionality and usage of the selection service. A | |
| provided <a href="#example">sample plug-in</a> demonstrates the workbench | |
| selection behaviour and can also serve for debugging purposes. | |
| </p> | |
| <h2>The Big Picture</h2> | |
| <p> | |
| Each workbench window has its own <i>selection service</i> instance. The | |
| service keeps track of the selection in the currently active part and | |
| propagates selection changes to all registered listeners. Such selection | |
| events occur when the selection in the current part is changed or when a | |
| different part is activated. Both can be triggered by user interaction or | |
| programmatically. | |
| </p> | |
| <img src="images/diagram1.gif" width="629" height="321" title="Diagram 1"> | |
| <p> | |
| The view where elements or text is selected does not need to know who is | |
| interested in the selection. Therefore we may create new views that depend on | |
| the selection of an existing view – without changing a single line of | |
| code in that view. | |
| </p> | |
| <p> | |
| The next sections explain <a href="#provider">who</a> provides | |
| <a href="#what">what</a> kind of selections to <a href="#listener">whom</a>. | |
| </p> | |
| <h2><a name="what">What can be selected?</h2> | |
| <p> | |
| From the users point of view a selection is a set of highlighted entries in a | |
| viewer like a table or tree widget. A selection can also be a piece of text in | |
| an editor. Behind the scene each visual element in the workbench is | |
| represented by a Java object. The MVC implementation of JFace maps | |
| between the domain model objects and the visual representations. | |
| </p> | |
| <p> | |
| Internally a selection is a data structure holding the model objects which | |
| corresponds to the graphical elements selected in the workbench. As pointed | |
| out before there are two fundamental different kinds of selections: | |
| </p> | |
| <ul> | |
| <li>A list of objects</li> | |
| <li>A piece of text</li> | |
| </ul> | |
| <p> | |
| Both can be empty, i.e. a empty list or a text string with zero length. | |
| Following the typical Eclipse philosophy these data structures are properly | |
| defined by interfaces: | |
| </p> | |
| <img src="images/diagram2.gif" width="445" height="270" title="Diagram 2"> | |
| <p> | |
| The | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/IStructuredSelection.html"><code>IStructuredSelection</code></a> | |
| refers to a list of objects. A special form of this is the | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ITreeSelection.html"><code>ITreeSelection</code></a> | |
| where each object in the list is described by a path. A path is a list of | |
| objects, for example the objects from the root to the selected object in a tree view. | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/ITextSelection.html"><code>ITextSelection</code></a> | |
| and | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/IMarkSelection.html"><code>IMarkSelection</code></a> | |
| describe a piece of selected text. | |
| </p> | |
| <p> | |
| For convenience there are default implementations for these interfaces: | |
| </p> | |
| <ul> | |
| <li><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/StructuredSelection.html"><code>org.eclipse.jface.viewers.StructuredSelection</code></a></li> | |
| <li><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/TreeSelection.html"><code>org.eclipse.jface.viewers.TreeSelection</code></a></li> | |
| <li><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/TextSelection.html"><code>org.eclipse.jface.text.TextSelection</code></a></li> | |
| <li><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/MarkSelection.html"><code>org.eclipse.jface.text.MarkSelection</code></a></li> | |
| </ul> | |
| <p> | |
| These implementations are used internally within the viewer when transforming | |
| low-level SWT events to | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ISelection.html"><code>ISelection</code></a> | |
| objects. The implementations are also useful when elements should be selected | |
| programmatically by some application code, for example: | |
| </p> | |
| <pre> | |
| ISelection sel = new StructuredSelection(presetElement); | |
| treeviewer.setSelection(sel); | |
| </pre> | |
| <blockquote> | |
| <p> | |
| <img src="images/tryit.gif" width="61" height="13"> | |
| Install the provided <a href="#example">sample plug-in</a> and check what | |
| kind of selections occur in different views. The | |
| <i>"Workbench Selection"</i> view shows the | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ISelection.html"><code>ISelection</code></a> | |
| implementation class and the selected elements or text itself. | |
| </p> | |
| </blockquote> | |
| <h2><a name="provider">Telling the Workbench Window about Selections</h2> | |
| <p> | |
| All JFace viewers are so called <i>selection providers</i>. A selection | |
| provider implements the interface | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ISelectionProvider.html"><code>ISelectionProvider</code></a>: | |
| </p> | |
| <img src="images/diagram3.gif" width="345" height="108" title="Diagram 3"> | |
| <p> | |
| The different JFace viewers accept and propagate different kind of selections: | |
| </p> | |
| <table> | |
| <tr> | |
| <td><b>Viewer</b></td> | |
| <td><b>Selection Type</b></td> | |
| </tr><tr> | |
| <td><code>ComboViewer</code></td> | |
| <td><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/IStructuredSelection.html"><code>IStructuredSelection</code></a></td> | |
| </tr><tr> | |
| <td><code>ListViewer</code></td> | |
| <td><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/IStructuredSelection.html"><code>IStructuredSelection</code></a></td> | |
| </tr><tr> | |
| <td><code>TreeViewer</code></td> | |
| <td><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/IStructuredSelection.html"><code>IStructuredSelection</code></a>, | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ITreeSelection.html"><code>ITreeSelection</code></a></td> | |
| </tr><tr> | |
| <td><code> +- CheckboxTreeViewer</code></td> | |
| <td><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/IStructuredSelection.html"><code>IStructuredSelection</code></a>, | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ITreeSelection.html"><code>ITreeSelection</code></td> | |
| </tr><tr> | |
| <td><code>TableViewer</code></td> | |
| <td><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/IStructuredSelection.html"><code>IStructuredSelection</code></a></td> | |
| </tr><tr> | |
| <td><code> +- CheckboxTableViewer</code></td> | |
| <td><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/IStructuredSelection.html"><code>IStructuredSelection</code></a></td> | |
| </tr><tr> | |
| <td><code>TextViewer</code></td> | |
| <td><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/ITextSelection.html"><code>ITextSelection</code></a>, | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/IMarkSelection.html"><code>IMarkSelection</code></a></td> | |
| </tr><tr> | |
| <td><code> +- SourceViewer</code></td> | |
| <td><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/ITextSelection.html"><code>ITextSelection</code></a>, | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/IMarkSelection.html"><code>IMarkSelection</code></a></td> | |
| </tr><tr> | |
| <td><code> +- ProjectionViewer</code></td> | |
| <td><a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/ITextSelection.html"><code>ITextSelection</code></a>, | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/text/IMarkSelection.html"><code>IMarkSelection</code></a></td> | |
| </tr> | |
| </table> | |
| <p> | |
| Also custom viewers may serve as selection providers and implement the | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ISelectionProvider.html"><code>ISelectionProvider</code></a> | |
| interface. | |
| </p> | |
| <p> | |
| Any workbench part that holds a viewer should register this viewer as the | |
| selection provider with the respective view site: | |
| </p> | |
| <pre> | |
| getSite().setSelectionProvider(tableviewer); | |
| </pre> | |
| <p> | |
| Even if you don't see a need for propagating your selection right now, this | |
| opens your plug-in for future extensions by you or by other plug-in | |
| implementers. If your view defines actions that depend on the current | |
| selection, setting a selection provider is also necessary to allow dynamic | |
| enablement of these actions. | |
| </p> | |
| <blockquote> | |
| <p> | |
| <img src="images/tip.gif" width="61" height="13"> | |
| Use the <a href="#example">sample plug-in</a> to check whether your views | |
| properly register selection providers. | |
| </p> | |
| </blockquote> | |
| <h2><a name="listener">Tracking the Current Selection</h2> | |
| <p> | |
| The workbench window is typically assembled in many parts, each coming with at | |
| least one viewer. The workbench keeps track about the currently selected part | |
| in the window and the selection within this part. Here starts the interesting | |
| part of the story: Plug-in implementations can access this information or | |
| register for notifications on selection changes. | |
| </p> | |
| <p> | |
| Each workbench window has an | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/ISelectionService.html"><code>ISelectionService</code></a> implementation | |
| which allows tracking the current selection. A view part can obtain a | |
| reference to it through its site: | |
| </p> | |
| <pre> | |
| getSite().getWorkbenchWindow().getSelectionService() | |
| </pre> | |
| <p> | |
| The selection service knows the current selection of the active part or of a | |
| part with a particular id: | |
| </p> | |
| <pre> | |
| ISelection getSelection() | |
| ISelection getSelection(String partId) | |
| </pre> | |
| <p> | |
| Typically views react on selection changes in the workbench window. In this | |
| case they better register an | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/ISelectionListener.html"><code>ISelectionListener</code></a> | |
| to get notified when the window's current selection changes: | |
| </p> | |
| <pre> | |
| void addSelectionListener(ISelectionListener listener) | |
| void removeSelectionListener(ISelectionListener listener) | |
| </pre> | |
| <p> | |
| Listeners registered in this way are notified when the selection in the active | |
| part is changed or when a different part is activated. Only selections within | |
| the active part are propagated. If the application is only interested in the | |
| selection of a particular part (independently of its actual activation) one | |
| may register the listener only for the respective part id: | |
| </p> | |
| <pre> | |
| void addSelectionListener(String partId, ISelectionListener listener) | |
| void removeSelectionListener(String partId, ISelectionListener listener) | |
| </pre> | |
| <p> | |
| This works even if there is currently no part with such a id. As soon as the | |
| part is created its initial selection will be propagated to the listeners | |
| registered for it. When the part is disposed, the listener is passed a | |
| <code>null</code> selection if the listener implements | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/INullSelectionListener.html"><code>INullSelectionListener</code></a> | |
| (see <a href="#nullselection">section below</a>). | |
| </p> | |
| <h3>Implementing a Selection Listener</h3> | |
| <p> | |
| The | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/ISelectionListener.html"><code>ISelectionListener</code></a> | |
| is a simple interface with just one method. A typical implementation | |
| looks like this: | |
| </p> | |
| <pre> | |
| private ISelectionListener mylistener = new ISelectionListener() { | |
| public void selectionChanged(IWorkbenchPart sourcepart, ISelection selection) { | |
| <img src="images/tag_1.gif" height="13" width="24" align="center"> if (sourcepart != MyView.this && | |
| <img src="images/tag_2.gif" height="13" width="24" align="center"> selection instanceof IStructuredSelection) { | |
| <img src="images/tag_3.gif" height="13" width="24" align="center"> doSomething(((IStructuredSelection) selection).toList()); | |
| } | |
| } | |
| }; | |
| </pre> | |
| <p> | |
| Depending on your requirements your listener implementation probably needs to | |
| deal with the following issues as shown in the code snippet above: | |
| </p> | |
| <ul> | |
| <li>In case we also provide selections (e.g. a view or editor) we should | |
| <img src="images/tag_1.gif" height="13" width="24" align="center"> | |
| exclude our own selection events from processing. This avoids unexpected | |
| results when the user selects elements within our part. | |
| </li> | |
| <li>Check whether we can handle this kind of selection | |
| (<img src="images/tag_2.gif" height="13" width="24" align="center">). | |
| </li> | |
| <li>Get the selected content from the selection and process it. | |
| (<img src="images/tag_3.gif" height="13" width="24" align="center">). | |
| </li> | |
| </ul> | |
| <blockquote> | |
| <p> | |
| <img src="images/tip.gif" width="61" height="13"> | |
| Don't mix the | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/ISelectionListener.html"><code>ISelectionListener</code></a> | |
| interface up with | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ISelectionChangedListener.html"><code>ISelectionChangedListener</code></a> | |
| used by JFace viewers to notify about selection changes. | |
| </p> | |
| </blockquote> | |
| <h3>Removing the Selection Listener</h3> | |
| <p> | |
| Don't forget to remove your selection listener when you can't handle events | |
| any more, e.g. when your view has been closed. The <code>dispose()</code> | |
| method is a good place to | |
| <img src="images/tag_1.gif" height="13" width="24" align="center"> remove your | |
| listener: | |
| </p> | |
| <pre> | |
| public void dispose() { | |
| ISelectionService s = getSite().getWorkbenchWindow().getSelectionService(); | |
| <img src="images/tag_1.gif" height="13" width="24" align="center"> s.removeSelectionListener(mylistener); | |
| super.dispose(); | |
| } | |
| </pre> | |
| <h2>More Selection Issues</h2> | |
| <p> | |
| Up to now we focused on the core functionality of the selection service, which covers most | |
| of the use cases. There are additional issues that might come into picture in implementation | |
| projects. | |
| </p> | |
| <h3>Post Selection</h3> | |
| <p> | |
| When navigating views the selection changes frequently - especially when the keyboard is | |
| used to scroll through long lists or the mouse is dragged over some text. This will lead | |
| to many unnecessary updates of the viewers registered as listeners to the selection service | |
| and may make your application less responsive. | |
| </p> | |
| <p> | |
| So called post selection events will be send-out with a slight delay. All intermediate | |
| selections during the delay time are ignored; just the final selection is propagated. | |
| The <code>ISelectionService</code> has additional methods to register listeners for the | |
| delayed selection events: | |
| </p> | |
| <pre> | |
| void addPostSelectionListener(ISelectionListener listener) | |
| void removePostSelectionListener(ISelectionListener listener) | |
| void addPostSelectionListener(String partId, | |
| ISelectionListener listener) | |
| void removePostSelectionListener(String partId, | |
| ISelectionListener listener) | |
| </pre> | |
| <p> | |
| To avoid performance issues viewers should typically register selection listeners this way. | |
| </p> | |
| <p> | |
| The selection providers are responsible for sending out the delayed events and have to | |
| implement the <code>IPostSelectionProvider</code> interface if they support it – all | |
| JFace viewers do so. | |
| </p> | |
| <blockquote> | |
| <p> | |
| <img src="images/tryit.gif" width="61" height="13"> | |
| Change the <a href="#example">sample plug-in</a> to listen to post selection events and | |
| check when they are sent. | |
| </p> | |
| </blockquote> | |
| <h3><a name="nullselection">INullSelectionListener</h3> | |
| <p> | |
| The call-back method <code>selectionChanged()</code> defined in | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/ISelectionListener.html"><code>ISelectionListener</code></a> | |
| get the new selection as well as the originating part passed in as parameters: | |
| </p> | |
| <pre> | |
| public void selectionChanged(IWorkbenchPart part, ISelection selection); | |
| </pre> | |
| <p> | |
| The | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/INullSelectionListener.html"><code>INullSelectionListener</code></a> | |
| interface extends | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/ISelectionListener.html"><code>ISelectionListener</code></a> | |
| but does not declare any additional methods. It is a pure marker interface to | |
| indicate that implementers of the <code>selectionChanged()</code> method wants | |
| to bet notified even with <code>null</code> parameters. This is usefull when | |
| you need to know that there is no current selection simply due to the fact | |
| that there is no one who provides a selection. You step into this when: | |
| </p> | |
| <ul> | |
| <li>The active part has not set a selection provider.</li> | |
| <li>The specific part we have registered our listener for has not set a selection provider.</li> | |
| <li>There is no active part in the workbench window, all parts are closed.</li> | |
| <li>The specific part we have registered our listener for has been closed.</li> | |
| </ul> | |
| <h3>Which Selection Service: Page or Window?</h3> | |
| <p> | |
| If you study the workbench API carefully you will find out that there | |
| are two selection services: The | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/IWorkbenchPage.html"><code>IWorkbenchPage</code></a> | |
| is a | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/ISelectionService.html"><code>ISelectionService</code></a>. | |
| On the other hand the | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/IWorkbenchWindow.html"><code>IWorkbenchWindow</code></a> | |
| has a method <code>getSelectionService()</code>. Therefore e.g. registering | |
| a listener within a part implementation is possible in two ways: | |
| </p> | |
| <pre> | |
| getSite().getWorkbenchWindow().getSelectionService().addSelectionListener(l); | |
| </pre> | |
| <p> | |
| or | |
| </p> | |
| <pre> | |
| getSite().getPage().addSelectionListener(l); | |
| </pre> | |
| <p> | |
| Actually this is totally equivalent because since Eclipse 2.0 a workbench | |
| window is limited to a single page only. Just don't mix both selection | |
| services when adding and removing a listener as two different implementations | |
| sit behind it. | |
| </p> | |
| <h3>Multiple Selection Providers Within a Part</h3> | |
| <p> | |
| Be aware that the part's site accepts a single selection provider only, | |
| which should be registered within the <code>createPartControl()</code> | |
| method only: | |
| </p> | |
| <pre> | |
| getSite().setSelectionProvider(provider); | |
| </pre> | |
| <p> | |
| Replacing the selection provider during the lifetime of the part is not | |
| properly supported by the workbench. If a part contains multiple viewers | |
| providing selections, like the <i>"Java Hierarchy"</i> view does, a intermediate | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ISelectionProvider.html"><code>ISelectionProvider</code></a> | |
| implementation has to be provided that allows dynamically delegating to the | |
| currently active viewer within the part. As a starting point you may look into | |
| <a href="SelectionProviderIntermediate.java"><code>SelectionProviderIntermediate.java</code></a> | |
| provided with this article. | |
| </p> | |
| <h3>What to do With the Selected Objects?</h3> | |
| <p> | |
| This article claims that the <i>selection service</i> helps to decouple | |
| views reacting on each others selection. But the view handling a selection | |
| still needs to deal with the selected objects to provide any useful | |
| functionality. Check out the | |
| <a href="http://wiki.eclipse.org/FAQ_How_do_I_use_IAdaptable_and_IAdapterFactory%3F">adapter pattern</a> | |
| provided by the Eclipse runtime core, which allows attaching new functionality | |
| to existing model objects or the other way round providing required | |
| functionality for newly contributed objects. | |
| </p> | |
| <p> | |
| Actually our <a href="#example">example plug-in</a> does exactly this by using the workbench label | |
| provider which in turn relies on the | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/model/IWorkbenchAdapter.html"><code>IWorkbenchAdapter</code></a> | |
| to retrieve icons and text labels for the listed objects. The same mechanism | |
| is utilized by the <i>"Properties"</i> view, see article | |
| <a href="http://www.eclipse.org/articles/Article-Properties-View/properties-view.html">"Take control of your properties"</a> | |
| for details. | |
| </p> | |
| <h2><a name="example">Example Plug-in </h2> | |
| <p> | |
| This article comes with a small example plug-in that demonstrates the | |
| explained techniques. Additionally the plug-in may serve for debugging your | |
| selection providers. The example contributes a new view | |
| <i>"Workbench Selection"</i> which simply mirrors the current selection in the | |
| workbench. It works for element selections as well as for text selections. | |
| </p> | |
| <h3>Getting and Running the Example</h3> | |
| <p> | |
| Download the plug-in | |
| <a href="com.mountainminds.eclipse.selectionsample_1.1.0.jar"><code>com.mountainminds.eclipse.selectionsample_1.1.0.jar</code></a> | |
| and import it into your workspace via the <i>"Import..."</i> wizard from the | |
| <i>"File"</i> menu. Select <i>"Existing Project into Workspace"</i> on the | |
| first wizard page. On the second page simply use the option | |
| <i>"Select archive file"</i> to import the downloaded archive. The fastest way | |
| to launch the example is right-clicking the plug-in project and select | |
| <a>"Run As"</a> → <a>"Eclipse Application"</a> in the context menu. | |
| </p> | |
| <p> | |
| If don't want to play with the source code you can also drop the bundle into | |
| an Eclipse installation and use it directly. | |
| </p> | |
| <p> | |
| From the menu of the launched workbench activate | |
| <a>"Window"</a> → <a>"Show View"</a> → <a>"Other..."</a> and select | |
| our view <i>"Workbench Selection"</i> in the category <a>"Other"</a>. Now you | |
| can play around with selections in various workbench parts and see how our | |
| <i>"Workbench Selection"</i> view reflects these selections: | |
| </p> | |
| <img src="images/screen2.gif" width="344" height="333" title="Screen 2"> | |
| <p> | |
| The same works for text selections: | |
| </p> | |
| <img src="images/screen3.gif" width="401" height="333" title="Screen 3"> | |
| <p> | |
| The example is implemented in a single class | |
| <a href="SelectionView.java"><code>SelectionView.java</code></a> applying the | |
| techniques discussed in this article. When reading through this short piece | |
| of code you may note that: | |
| </p> | |
| <ul> | |
| <li> | |
| The <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/ISelectionListener.html"><code>ISelectionListener</code></a> | |
| implementation makes sure that we do not react on our own selections. | |
| </li> | |
| <li> | |
| The title of the source part of the current selection as well as the | |
| implementation class of | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/ISelection.html"><code>ISelection</code></a> | |
| is shown in the view description (the optional grey bar at the top). | |
| </li> | |
| <li> | |
| The view uses two viewers: One for object lists and one for text blocks. | |
| Switching between the viewers is implemented done with a | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/part/PageBook.html"><code>PageBook</code></a>. | |
| <li> | |
| </li> | |
| The viewer for object lists itself registeres as a selection provider. | |
| Check it out: If you select a element listed in our | |
| <i>"Workbench Selection"</i> view its properties are shown in turn in the | |
| <i>"Properties"</i> view. | |
| </li> | |
| </ul> | |
| <h2>Conclusion</h2> | |
| <p> | |
| The mechanisms provided by the Eclipse workbench are simple to use and | |
| powerful. Not using this mechanisms result in plug-ins that poorly integrate | |
| with the rest of the workbench and will be hard to extend. To avoid such | |
| pitfalls simply follow these rules when selections come into picture: | |
| </p> | |
| <ul> | |
| <li> | |
| Avoid direct hard-wired inter-view communication. If one view needs to react | |
| on the selection in another view use the <code>ISelectionService</code>. | |
| </li> | |
| <li> | |
| Be cooperative and open for future extensions: Always register your viewers | |
| as selection providers with the part site. | |
| </li> | |
| <li> | |
| Use existing selection specific views like the <i>"Properties"</i> view when | |
| appropriate instead of creating new ones. | |
| </li> | |
| </ul> | |
| <h2>References</h2> | |
| <ul> | |
| <li> | |
| OTI Inc., Eclipse Platform Technical Overview, 2003<br> | |
| <a href="http://www.eclipse.org/whitepapers/eclipse-overview.pdf">http://www.eclipse.org/whitepapers/eclipse-overview.pdf</a> | |
| </li> | |
| <li> | |
| eclipse.org, JFace Viewer Package, 2005<br> | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/package-summary.html">http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/jface/viewers/package-summary.html</a> | |
| </li> | |
| <li> | |
| eclipse.org, Workbench UI Package, 2005<br> | |
| <a href="http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/package-summary.html">http://help.eclipse.org/ganymede/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/ui/package-summary.html</a> | |
| </li> | |
| <li> | |
| wiki.eclipse.org, FAQ How do I find out what object is selected?, 2006<br> | |
| <a href="http://wiki.eclipse.org/FAQ_How_do_I_find_out_what_object_is_selected%3F">http://wiki.eclipse.org/FAQ_How_do_I_find_out_what_object_is_selected%3F</a> | |
| </li> | |
| <li> | |
| wiki.eclipse.org, FAQ How do I make a view respond to selection changes in another view?, 2006<br> | |
| <a href="http://wiki.eclipse.org/FAQ_How_do_I_make_a_view_respond_to_selection_changes_in_another_view%3F">http://wiki.eclipse.org/FAQ_How_do_I_make_a_view_respond_to_selection_changes_in_another_view%3F</a> | |
| </li> | |
| <li> | |
| wiki.eclipse.org, FAQ How do I use IAdaptable and IAdapterFactory?, 2006<br> | |
| <a href="http://wiki.eclipse.org/FAQ_How_do_I_use_IAdaptable_and_IAdapterFactory%3F">http://wiki.eclipse.org/FAQ_How_do_I_use_IAdaptable_and_IAdapterFactory%3F</a> | |
| </li> | |
| <li> | |
| Dicky Johan, Take control of your properties, 2003<br> | |
| <a href="http://www.eclipse.org/articles/Article-Properties-View/properties-view.html">http://www.eclipse.org/articles/Article-Properties-View/properties-view.html</a> | |
| </li> | |
| </ul> | |
| <p> | |
| To discuss or report problems in this article see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=112193">bug 112193</a>. | |
| </p> | |
| <h2>Resources</h2> | |
| <p> | |
| This article come with the following resources: | |
| </p> | |
| <ul> | |
| <li> | |
| Example plug-in providing the <i>"Workbench Selection"</i> view<br> | |
| <a href="com.mountainminds.eclipse.selectionsample_1.1.0.jar">com.mountainminds.eclipse.selectionsample_1.1.0.jar</a> | |
| </li> | |
| <li> | |
| Selection provider implementation for delegating to multiple other selection providers<br> | |
| <a href="SelectionProviderIntermediate.java">SelectionProviderIntermediate.java</a> | |
| </li> | |
| </ul> | |
| </body> | |
| </html> |