Typically, a tree view is used to show content in a hierarchical manner. However, a tree on its own is not enough to be able to show all the details associated with an object. When the user double-clicks on an element, more details can be shown.
TimeZoneTreeView
, register a lambda block that implements the IDoubleClickListener
interface with the addDoubleClickListener
method on the treeViewer
. As with the example in Chapter 1, Creating Your First Plug-in, this will open a message dialog to verify that it works as expected:treeViewer.addDoubleClickListener(event -> { Viewer viewer = event.getViewer(); Shell shell = viewer.getControl().getShell(); MessageDialog.openInformation(shell, "Double click", "Double click detected"); });
ISelection
interface (which only provides an isEmpty
method) and an IStructuredSelection
(which provides an iterator and other accessor methods). There are also a couple of specialized subtypes, such as ITreeSelection
, which can be interrogated for the path that led to the selection in the tree. In the create
method of the TimeZoneTreeView
class, where the doubleClick
method of the DoubleClickListener
lambda is present, replace the MessageDialog
as follows:// MessageDialog.openInformation(shell, "Double click", // "Double click detected"); ISelection sel = viewer.getSelection(); Object selectedValue; if (!(sel instanceof IStructuredSelection) || sel.isEmpty()) { selectedValue = null; } else { selectedValue = ((IStructuredSelection)sel).getFirstElement(); } if (selectedValue instanceof ZoneId) { ZoneId timeZone = (ZoneId)selectedValue; MessageDialog.openInformation(shell, timeZone.getId(), timeZone.toString()); }
ZoneId
string representation.ZoneId
in the displayed window, create a subclass of MessageDialog
called TimeZoneDialog
in the com.packtpub.e4.clock.ui.internal
package:public class TimeZoneDialog extends MessageDialog { private ZoneId timeZone; public TimeZoneDialog(Shell parentShell, ZoneId timeZone) { super(parentShell, timeZone.getId(), null, "Time Zone " + timeZone.getId(), INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0); this.timeZone = timeZone; } }
TimeZoneDialog
content is created in the createCustomArea
method, which can be implemented as follows:protected Control createCustomArea(Composite parent) { ClockWidget clock = new ClockWidget(parent,SWT.NONE, new RGB(128,255,0)); return parent; }
TimeZoneTreeView
call to MessageDialog.open()
to use the TimeZoneDialog
instead:if (selectedValue instanceof ZoneId) { ZoneId timeZone = (ZoneId) selectedValue; // MessageDialog.openInformation(shell, timeZone.getID(), // timeZone.toString()); new TimeZoneDialog(shell, timeZone).open(); }
A double-click listener was added to the viewer by registering it with addDoubleClickListener
. Initially, a standard information dialog was displayed; but then a custom subclass of MessageDialog
was used which included a ClockWidget
. In order to get the appropriate ZoneId
, it was accessed via the currently selected object from the TreeViewer
.
Selection handled by viewers is managed through an ISelection
interface. The viewer's getSelection
method should always return a non-null value, although it may be isEmpty
. There are two relevant sub-interfaces: IStructuredSelection
and ITreeSelection
.
The ITreeSelection
interface is a subtype of IStructuredSelection
, which adds methods specific to trees. This includes the ability to find out what the selected object(s) and their parents are in the tree.
The IStructuredSelection
interface is the most commonly used interface when dealing with selection types for viewers. If the selection is not empty, it is almost always an instance of an IStructuredSelection
. As a result, the following snippet of code appears regularly:
ISelection sel = viewer.getSelection(); Object selectedValue; if (!(sel instanceof IStructuredSelection) || sel.isEmpty()) { selectedValue = null; } else { selectedValue = ((IStructuredSelection)sel).getFirstElement(); }
This snippet gets the selection from the viewer, and if it's not an IStructuredSelection
, or it's empty, assigns null
to selectedValue
. If it's not empty, it casts it to IStructuredSelection
and calls getFirstElement
to get the single selected value.
Note that the selection may have more than one selected value, in which case the getFirstElement
only returns the first selected element. IStructuredSelection
provides an iterator to step through all selected objects.
3.128.171.246