Time for action – adding items to the tray
Most operating systems have a concept of tray, as a set of icons visible from the main window that can provide quick access components. On macOS, these are represented as icons across the top menu bar, and on Windows, as icons on the bottom-right near the clock. Linux systems have various approaches that do similar things, and some operating systems have none. Since there is only one tray, it is necessary to add the item only once. The Activator
class can be used to ensure that the TrayItem
is created at startup and removed at shutdown.
- Open the
Activator
class, and add two private fields:private TrayItem trayItem; private Image image;
- Add the following to the
start
method:final Display display = Display.getDefault(); display.asyncExec(() -> { image = new Image(display, Activator.class.getResourceAsStream("/icons/sample.gif")); Tray tray = display.getSystemTray(); if (tray != null && image != null) { trayItem = new TrayItem(tray, SWT.NONE); trayItem.setToolTipText("Hello World"); trayItem.setVisible(true); trayItem.setText("Hello World"); trayItem.setImage(image); } });
- Run the target Eclipse instance, and show the Clock View. The small
sample.gif
icon should appear in the task area (top right in macOS, bottom right in Windows). - To test the effect of stopping and restarting the bundle, open the Console View in the target Eclipse instance. Click on the drop-down on the top right of the view to create a Host OSGi Console:
WARNING: This console is connected to the current running instance of Eclipse! osgi> "Framework is launched."
- Type
ss clock
at the osgi> prompt and it will show a bundle ID, which can be used to start/stop:osgi> ss clock id State Bundle 4 RESOLVED com.packtpub.e4.clock.ui_1.0.0.qualifier
- Start and stop the bundle by typing
start
andstop
into the console with theID
given the preceding output:osgi> stop 4 osgi> start 4 osgi> stop 4 osgi> start 4
- Notice that a new
TrayItem
appears in theTray
each time it is started. The clean routine needs to be added in theActivator
methodstop
:public void stop(BundleContext context) throws Exception { if (trayItem != null) { Display.getDefault().asyncExec(trayItem::dispose); } if (image != null) { Display.getDefault().asyncExec(image::dispose); }
- Re-run the application and start and stop the bundle—the SWT tray icon should go and come back each time the bundle is stopped and started.
What just happened?
An SWT TrayItem
is added to the system's Tray
when the bundle is started and removed when the bundle is stopped. The icon that came with the sample project was used. To use a different one, don't forget to update the build.properties
file.
Since the tray is a graphical component, if there's no image, then the item isn't shown. The tooltips are optional. Note also that not every system has the concept of a tray, so null
is a legitimate return value for display.getSystemTray()
.
A bundle is started automatically when it is loaded, and the loading is triggered by showing a view or selecting a menu item. If a view is opened, the bundle that class is loaded from is automatically started. Bundles can also be started and stopped programmatically, or through the Host OSGi Console, which is useful to test whether the Activator
class's start
and stop
methods are working correctly.