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.
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 enter org.eclipse.e4.ui.services
.TimeZoneTableView
class, create a method called setTimeZone
. 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) { }
null
, set the value on the tableViewer
using the setSelection
method. Since this takes an ISelection
type, wrap the selected TimeZone
within a StructuredSelection
instance as follows:if (timeZone != null) { // NOTE may generate a NullPointerException tableViewer.setSelection(new StructuredSelection(timeZone)); tableViewer.reveal(timeZone); }
NullPointerException
will be thrown from inside the setSelection
call, which indicates that the tableViewer
variable is null
. The reason is because the call to set the time zone occurs before the @PostConstruct
annotated method is called, so the tableViewer
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 surrounding if
block that checks to see that the tableViewer
is not null
:if (timeZone != null && tableViewer != null) { tableViewer.setSelection(new StructuredSelection(timeZone)); tableViewer.reveal(timeZone); }
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.
Now that the selection works from the tree viewer to the table viewer, try the following:
setTimeZone
method to the TimeZoneTreeViewer
to allow the selection to display items in the tree viewer.SelectionChangeListener
to the TimeZoneTableViewer
so that a selection in the table view will trigger a change in other views.setTimeZone
methods, check that the tableViewer
hasn't been disposed as well as the null check.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.StructuredChangeListener
class that can forward selection events to a generic JFace viewer which can be re-used.ESelectionService
with a non-optional Provider<ESelectionService>
, and use the get
method to acquire the selection service on demand or pass it into the generic class created in the previous step.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?
18.116.85.72