Time for action – responding to selection changes
When the selection is changed in the E4 selection service, parts can be notified that a new selection is available through injection. Although an @Inject
field could be used, there would be no trigger that could be used to update the view. Instead, a method with an injected parameter will be used to trigger the update.
- Add the required packages to the bundle's package imports, by right-clicking on the
com.packtpub.e4.clock.ui
project and navigating to Plug-in Tools | Open Manifest to open the bundle's manifest. On the Dependencies tab, click on Add under the Imported Packages section and enterorg.eclipse.e4.ui.services
. - In the
TimeZoneTableView
class, create a method calledsetTimeZone
. The method name isn't specifically important, but the method needs to be annotated with@Inject
and@Optional
, and the argument needs to be annotated with@Named(IServiceConstants.ACTIVE_SELECTION)
. It should look like:@Inject @Optional public void setTimeZone( @Named(IServiceConstants.ACTIVE_SELECTION) ZoneId timeZone) { }
- In the method, if the selection is not
null
, set the value on thetableViewer
using thesetSelection
method. Since this takes anISelection
type, wrap the selectedTimeZone
within aStructuredSelection
instance as follows:if (timeZone != null) { // NOTE may generate a NullPointerException tableViewer.setSelection(new StructuredSelection(timeZone)); tableViewer.reveal(timeZone); }
- If the application is run, a
NullPointerException
will be thrown from inside thesetSelection
call, which indicates that thetableViewer
variable isnull
. The reason is because the call to set the time zone occurs before the@PostConstruct
annotated method is called, so thetableViewer
has not been instantiated yet. The solution is to ignore selection events when the viewer has not been constructed, by adding a guard to the surroundingif
block that checks to see that thetableViewer
is notnull
:if (timeZone != null && tableViewer != null) { tableViewer.setSelection(new StructuredSelection(timeZone)); tableViewer.reveal(timeZone); }
- Now when the application is run, and a time zone is selected in the Time Zone Tree View, the corresponding object should be selected in the Time Zone Table View.
What just happened?
The selected object is stored in the E4 scope, with the key specified in the IServiceConstants.ACTIVE_SELECTION
constant. When the selection changes, the setTimeZone
method is automatically called. To prevent problems with propagating empty selections, if the selected value is null
then it is not forwarded on.
Since the selection can change and be set at any time, including before the part is fully constructed, it is necessary to guard the code to ignore selections if the viewer is null
.
The treeViewer
expects a value of type ISelection
, so the time zone is wrapped in a StructuredSelection
instance, and then passed to the treeViewer
. The reveal step is optional, and will focus the viewer on the selected object if it is available.
Have a go hero – adding selection support to the table view
Now that the selection works from the tree viewer to the table viewer, try the following:
- Add a
setTimeZone
method to theTimeZoneTreeViewer
to allow the selection to display items in the tree viewer. - Add a
SelectionChangeListener
to theTimeZoneTableViewer
so that a selection in the table view will trigger a change in other views. - In the
setTimeZone
methods, check that thetableViewer
hasn't been disposed as well as the null check. - To prevent calls to the
setTimeZone
method from taking effect before the viewer has been constructed, assign the viewer to a local variable in the corresponding@PostContstruct
method first, and then at the end of the method assign the local variable to the field. - Create a standard
StructuredChangeListener
class that can forward selection events to a generic JFace viewer which can be re-used. - Convert the optional
ESelectionService
with a non-optionalProvider<ESelectionService>
, and use theget
method to acquire the selection service on demand or pass it into the generic class created in the previous step.
Pop quiz – understanding selection
Q1. How do viewers work with selected objects?
Q2. What event listener is used to receive notifications of a viewer's selection updates?
Q3. What service is used in E4 to maintain the selected object in the current window?
Q4. How does the selected object in E4 get propagated to parts?