package envoy.client.ui; import java.awt.AWTException; import java.awt.Image; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.TrayIcon.MessageType; import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.HashSet; import java.util.Set; import envoy.client.event.Event; import envoy.client.event.EventBus; import envoy.client.event.EventHandler; import envoy.client.event.MessageCreationEvent; import envoy.exception.EnvoyException; import envoy.schema.Message; /** * Project: envoy-client
* File: StatusTrayIcon.java
* Created: 3 Dec 2019
* * @author Kai S. K. Engelbart * @since Envoy v0.2-alpha */ public class StatusTrayIcon implements EventHandler { /** * The {@link TrayIcon} provided by the System Tray API for controlling the * system tray. This includes displaying the icon, but also creating * notifications when new messages are received. */ private TrayIcon trayIcon; /** * A received {@link Message} is only displayed as a system tray notification if * this variable is set to {@code true}. */ private boolean displayMessages = false; /** * Creates a {@link StatusTrayIcon} with the Envoy logo, a tool tip and a pop-up * menu. * * @param focusTarget the {@link Window} which focus determines if message * notifications are displayed * @throws EnvoyException if the currently used OS does not support the System * Tray API * @since Envoy v0.2-alpha */ public StatusTrayIcon(Window focusTarget) throws EnvoyException { if (!SystemTray.isSupported()) throw new EnvoyException("The Envoy tray icon is not supported."); ClassLoader loader = Thread.currentThread().getContextClassLoader(); Image img = Toolkit.getDefaultToolkit().createImage(loader.getResource("envoy_logo.png")); trayIcon = new TrayIcon(img, "Envoy Client"); trayIcon.setImageAutoSize(true); trayIcon.setToolTip("You are notified if you have unread messages."); PopupMenu popup = new PopupMenu(); MenuItem exitMenuItem = new MenuItem("Exit"); exitMenuItem.addActionListener((evt) -> System.exit(0)); popup.add(exitMenuItem); trayIcon.setPopupMenu(popup); // Only display messages if the chat window is not focused focusTarget.addWindowFocusListener(new WindowAdapter() { @Override public void windowGainedFocus(WindowEvent e) { displayMessages = false; } @Override public void windowLostFocus(WindowEvent e) { displayMessages = true; } }); // Start processing message events EventBus.getInstance().register(this); } /** * Makes this {@link StatusTrayIcon} appear in the system tray. * * @throws EnvoyException if the status icon could not be attaches to the system * tray for system-internal reasons * @since Envoy v0.2-alpha */ public void show() throws EnvoyException { try { SystemTray.getSystemTray().add(trayIcon); } catch (AWTException e) { throw new EnvoyException("Could not attach Envoy tray icon to system tray.", e); } } /** * Notifies the user of a message by displaying a pop-up every time a new * message is received. * * @since Envoy v0.2-alpha */ @Override public void handle(Event event) { System.out.println("Message received. Displaying message: " + displayMessages); if (displayMessages) trayIcon.displayMessage("New message received", ((MessageCreationEvent) event).get().getContent().get(0).getText(), MessageType.INFO); } /** * The {@link StatusTrayIcon} only reacts to {@link MessageCreationEvent} * instances which signify newly received messages. * * @return A set with the single element {@code MessageCreationEvent.class} * @since Envoy v0.2-alpha */ @Override public Set>> supports() { Set>> supportedEvents = new HashSet<>(); supportedEvents.add(MessageCreationEvent.class); return supportedEvents; } }