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.
createPartControl()
method of TimeZoneTreeView
, register an anonymous inner class 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(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent 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's 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 createPartControl()
method of TimeZoneTreeView
, where the doubleClick()
method of the DoubleClickListener
inner class is present, replace the MessageDialog
as follows://The following commented code needs to be replaced /*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 TimeZone) { TimeZone timeZone = (TimeZone)selectedValue; MessageDialog.openInformation(shell, timeZone.getID(), timeZone.toString()); }
TimeZone
.TimeZone
in the displayed window, create a subclass of MessageDialog
called TimeZoneDialog
in the com.packtpub.e4.clock.ui.internal
package. Implement it as follows:public class TimeZoneDialog extends MessageDialog { private TimeZone timeZone; public TimeZoneDialog(Shell parentShell, TimeZone timeZone) { super(parentShell, timeZone.getID(), null, "Time Zone " + timeZone.getID(), INFORMATION, new String[] { IDialogConstants.OK_LABEL }, 0); this.timeZone = timeZone; } }
Dialog
are provided by the customArea()
method, which can be used to build up the view. Add the following createCustomArea()
method to the TimeZoneDialog
:protected Control createCustomArea(Composite parent) { ClockWidget clock = new ClockWidget(parent,SWT.NONE, new RGB(128,255,0)); clock.setOffset( (TimeZone.getDefault().getOffset(System.currentTimeMillis()) - timeZone.getOffset(System.currentTimeMillis())) /3600000); return parent; }
MessageDialog.open()
by TimeZoneTreeView
to use the new implementation:if (selectedValue instanceof TimeZone) { TimeZone timeZone = (TimeZone) selectedValue; //The following commented code needs to be removed /*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 TimeZone
, it was accessed via the currently selected object from the TreeViewer
.
Selection is managed via an ISelection
interface. The viewer's getSelection()
method should always return a non-null value, although the value may return true
for the isEmpty()
call. There are two relevant subinterfaces; IStructuredSelection
and ITreeSelection
.
The ITreeSelection
is a subtype of IStructuredSelection
, and adds methods specific to trees. This includes the ability to find out what the selected object(s) are and what their parents are in the tree.
The IStructuredSelection
is the most commanly used interface in dealing with selection types. 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, it assigns the variable selectedValue
to null
. If it's non-empty, it casts it to the IStructuredSelection
interface and calls getFirstElement()
to get the single selected value.
The selection may have more than one selected value, in which case the getFirstElement()
method only returns the first element selected. The IStructuredSelection
class provides an iterator to step through all selected objects.