package envoy.client.ui; import java.awt.*; import java.awt.TrayIcon.MessageType; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.logging.Level; import envoy.client.event.MessageCreationEvent; import envoy.data.Message; import envoy.event.EventBus; import envoy.exception.EnvoyException; import envoy.util.EnvoyLog; /** * Project: envoy-client
* File: StatusTrayIcon.java
* Created: 3 Dec 2019
* * @author Kai S. K. Engelbart * @since Envoy Client v0.2-alpha */ public class StatusTrayIcon { /** * 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 final 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 Client v0.2-alpha */ public StatusTrayIcon(Window focusTarget) throws EnvoyException { if (!SystemTray.isSupported()) throw new EnvoyException("The Envoy tray icon is not supported."); final ClassLoader loader = Thread.currentThread().getContextClassLoader(); final 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."); final PopupMenu popup = new PopupMenu(); final 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; } }); // Show the window if the user clicks on the icon trayIcon.addActionListener(evt -> { focusTarget.setVisible(true); focusTarget.requestFocus(); }); // Start processing message events // TODO: Handle other message types EventBus.getInstance() .register(MessageCreationEvent.class, evt -> { if (displayMessages) trayIcon.displayMessage("New message received", evt.get().getText(), MessageType.INFO); }); } /** * 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 Client v0.2-alpha */ public void show() throws EnvoyException { try { SystemTray.getSystemTray().add(trayIcon); } catch (final AWTException e) { EnvoyLog.getLogger(StatusTrayIcon.class).log(Level.INFO, "Could not display StatusTrayIcon: ", e); throw new EnvoyException("Could not attach Envoy tray icon to system tray.", e); } } }