A new TimeZoneView
will show a list of clocks in time zones around the world. This time, instead of using the plug-in wizard, the extension will be added manually.
The way views are defined for E4 is covered in Chapter 7, Creating Eclipse 4 Applications. This chapter discusses how to do it in Eclipse 3.x and the Eclipse 3.x compatibility model of Eclipse 4.x.
plugin.xml
file in the navigator and double-click on it.org.eclipse.ui.views
. Expand this, and underneath the Timekeeping (category) the Clock View (view) will be displayed, added via the plug-in wizard.com.packtpub.e4.clock.ui.views.TimeZoneView
Time Zone View
com.packtpub.e4.clock.ui.views.TimeZoneView
com.packtpub.e4.clock.ui
icons/sample.gif
plugin.xml
file:<view category="com.packtpub.e4.clock.ui" class="com.packtpub.e4.clock.ui.views.TimeZoneView" icon="icons/sample.gif" id="com.packtpub.e4.clock.ui.views.TimeZoneView" name="Time Zone View" restorable="true"> </view>
TimeZoneView
class. The easiest way is to go to the Extensions tab of the plugin.xml
file, select the Time Zone View, and click on the hyperlinked class* label next to the class name. Alternatively, navigate to File | New | Class wizard to create the TimeZoneView
as a subclass of ViewPart
, in the com.packtpub.e4.clock.ui.views
package.TimeZoneComparator
, which implements Comparator
, in a new package com.packtpub.e4.clock.ui.internal
. It is conventional to provide utility classes in an internal package to ensure that the implementation is not visible to others. The compare
method should use the Id
property of the ZoneId
and use the String's compareTo
method:public class TimeZoneComparator implements Comparator<ZoneId> { public int compare(ZoneId o1, ZoneId o2) { return o1.getId().compareTo(o2.getId()); } }
public static
method to the TimeZoneComparator
called getTimeZones
, which will return a Map
of Set
instances containing ZoneId
instances. The Map
will be indexed by the region of the ZoneId
(a ZoneId
is something like Europe/Milton_Keynes
or America/New_York
). This will group all the European ZoneId
instances together and all ZoneId
instances in America together:public static Map<String, Set<ZoneId>> getTimeZones(){ Supplier<Set<ZoneId>> sortedZones = () -> new TreeSet<>(new TimeZoneComparator()); return ZoneId.getAvailableZoneIds().stream() // stream .filter(s -> s.contains("/")) // with / in them .map(ZoneId::of) // convert String to ZoneId .collect(Collectors.groupingBy( // and group by z -> z.getId().split("/")[0], TreeMap::new, Collectors.toCollection(sortedZones) )); }
TimeZoneView
class's createPartControl
method, create a CTabFolder
and then iterate through the time zones, creating a CTabItem
for each one:public void createPartControl(Composite parent) { Map<String, Set<ZoneId>> timeZones = TimeZoneComparator.getTimeZones(); CTabFolder tabs = new CTabFolder(parent, SWT.BOTTOM); timeZones.forEach((region, zones) -> { CTabItem item = new CTabItem(tabs, SWT.NONE); item.setText(region); } tabs.setSelection(0); }
while
loop, add a Composite
to hold multiple ClockWidget
instances for each ZoneId
group:item.setText(region); // from before Composite clocks = new Composite(tabs, SWT.NONE); clocks.setLayout(new RowLayout()); item.setControl(clocks);
ZoneId
instances, adding a ClockWidget
for each: RGB rgb = new RGB(128, 128, 128); zones.forEach(zone -> { ClockWidget clock = new ClockWidget(clocks, SWT.NONE, rgb); clock.setZone(zone); }
Group
with an associated text label so that the view hierarchy goes from CTabItem
– Composite
– ClockWidget
to CTabItem
– Composite
– Group
– ClockWidget
. Replace the call to create the the ClockWidget
with this:// ClockWidget clock = new ClockWidget(clocks, SWT.NONE, rgb); Group group = new Group(clocks, SWT.SHADOW_ETCHED_IN); group.setText(zone.getId().split("/")[1]); ClockWidget clock = new ClockWidget(group, SWT.NONE, rgb);
Composite
is null
, Group
instances don't have a layout manager—and so the clocks are not getting sized appropriately. This can be fixed by setting a layout manager explicitly:group.setLayout(new FillLayout());
ScrolledComposite
class can be used. This provides automatic scroll bars and interaction with the user to permit a much larger virtual area to be scrolled. The view hierarchy will change from CTabItem
– Composite
– Group
– ClockWidget
to CTabItem
– ScrolledComposite
– Composite
– Group
– ClockWidget
instead:// Composite clocks = new Composite(tabs, SWT.NONE); // item.setControl(clocks); ScrolledComposite scrolled = new ScrolledComposite(tabs, SWT.H_SCROLL | SWT.V_SCROLL); Composite clocks = new Composite(scrolled, SWT.NONE); item.setControl(scrolled); scrolled.setContent(clocks); clocks.setLayout(new RowLayout());
ScrolledComposite
has no minimum size. This can be calculated from the clocks container by adding this to the bottom of the while
loop, after the contents of the ScrolledComposite
have been created:Point size = clocks.computeSize(SWT.DEFAULT, SWT.DEFAULT); scrolled.setMinSize(size); scrolled.setExpandHorizontal(true); scrolled.setExpandVertical(true);
ScrolledComposite
has a different background. To change it, add this line after constructing the clock's Composite
:clocks.setBackground(clocks.getDisplay() .getSystemColor(SWT.COLOR_LIST_BACKGROUND));
A combination of Composite
types created a tabbed interface using CTabFolder
and CTabItem
instances. Inside each CTabItem
, a ScrolledComposite
contained a Composite
of Group
instances, each of which had a single ClockWidget
. Adding the ScrolledComposite
provided the scrolling for free, and the Group
allowed us to place text above the ClockWidget
to display its time zone.
Some of the components used here are in the org.eclipse.swt.custom
package instead of the org.eclipse.swt.widgets
package. Several of these begin with C as a custom designator to distinguish similarly named widgets. The CTabFolder/Item
is an SWT-implemented class that provides the tab functionality; the corresponding OS widget, TabFolder/Item
, uses a native rendered tab switcher.
Q1. How do you add an icon to the system menu?
Q2. What does the SWT.NO_TRIM
style do for a Shell
?
Q3. How do you make a Shell
transparent?
Q4. What do you need to set to create a non-rectangular Shell
?
Q5. What Composite
allows you to attach a label to a set of related items?
Q6. What is the default layout manager for a Group
?
Q7. How do you add scrolling to an existing widget?
A set of times are displayed in different time zones, but there is scope for enhancements:
Thread
to update all clocksScrollableComposite
so that more than one row is displayed18.191.240.80