TL;DR: Is there a way, preferrably adhering to design pattern best practices, to process ISelections from multiple ISelectionProviders in an ISelectionListener without breaking loose coupling, and without guessing (type checks, casting)?
In my Eclipse RCP 3.7 application, I have two views and one (GEF) editor. The views contain checklists which allow the user to control the contents of the editor via selection. Assuming the editor displays university staff hierarchies, one view would allow to select the departments whose staff should be displayed, the other would allow to select the current degree levels for which staff should be displayed.
I.e., if the user selected Computer Science and English Literature in one view, and Post-Doc and Full Professor* in the the other, the editor would display staff (as, e.g., nodes) which are either Post-Docs or Full Professors from the CS or EngLit departments. The model, however, contains all staff from all depts.
I've implemented views and editor according to Eclipse Workbench: Using the Selection Service: The editor has an org.eclipse.ui.ISelectionListener, the views both implement org.eclipse.jface.viewers.ISelectionProvider. The views maintain a list of listeners, which are notified in a loop whenever a selection changes:
((ISelectionChangedListener) listeners.getListeners()[i]).selectionChanged(
new SelectionChangedEvent(DeptView.this,
new StructuredSelection({selection})))
I've tried the following implementations so far, but am not happy with either.
For
{selection}, use a custom class (e.g.,DeptSelection), which encapsulates the selected elements, or rather the model elements they point to. I think that this breaks loose coupling, asDeptSelectionwould be defined in the Dept Plugin, which would be separate from the Editor Plugin, and at the same time I want to allow clients to add extensions for whose selections the listener would also be able to listen.For
{selection}, simply pass the selected elements (in this case viaorg.eclipse.jface.viewers.CheckboxTableViewer#getCheckedElements()), and do the processing inISelectionListener#selectionChanged()in the editor. This is clumsy, as it involves a lot of guessing: type checks, casting, etc. Also, for this solution I then "save" the selections in an abstract util classSelectionUtil, which is read in the editor (here, the root edit part's contents edit part) to add the respective model elements to the list returned byAbtractEditPart'sgetModelChildren(). I'm (a) not sure whether the use of an abstract util class breaks loose coupling, and (b) whether having an abstract util class at all is a good design pattern.
Hence my question: Is there a non-clumsy way, preferrably adhering to design pattern best practices, to process multiple ISelections without breaking loose coupling?
*I know, not the most accurate example, as "Full Professor" and "Post-Doc" aren't exactly degrees.
Aucun commentaire:
Enregistrer un commentaire