package envoy.client.ui; import java.awt.*; import java.awt.TrayIcon.MessageType; import javafx.application.Platform; import javafx.stage.Stage; import envoy.client.util.IconUtil; import envoy.data.Message; import dev.kske.eventbus.*; import dev.kske.eventbus.Event; /** * @author Kai S. K. Engelbart * @since Envoy Client v0.2-alpha */ public final class StatusTrayIcon implements EventListener { /** * 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; /** * @return {@code true} if the status tray icon is supported on this platform * @since Envoy Client v0.2-beta */ public static boolean isSupported() { return SystemTray.isSupported(); } /** * Creates a {@link StatusTrayIcon} with the Envoy logo, a tool tip and a pop-up * menu. * * @param stage the stage whose focus determines if message * notifications are displayed * @since Envoy Client v0.2-beta */ public StatusTrayIcon(Stage stage) { trayIcon = new TrayIcon(IconUtil.loadAWTCompatible("/icons/envoy_logo.png"), "Envoy"); 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 -> { Platform.exit(); System.exit(0); }); popup.add(exitMenuItem); trayIcon.setPopupMenu(popup); // Only display messages if the stage is not focused stage.focusedProperty().addListener((ov, onHidden, onShown) -> displayMessages = !ov.getValue()); // Show the window if the user clicks on the icon trayIcon.addActionListener(evt -> Platform.runLater(() -> { stage.setIconified(false); stage.toFront(); stage.requestFocus(); })); // Start processing message events EventBus.getInstance().registerListener(this); } /** * Makes the icon appear in the system tray. * * @since Envoy Client v0.2-alpha */ public void show() { try { SystemTray.getSystemTray().add(trayIcon); } catch (final AWTException e) {} } /** * Removes the icon from the system tray. * * @since Envoy Client v0.2-beta */ public void hide() { SystemTray.getSystemTray().remove(trayIcon); } @Event private void onMessage(Message message) { if (displayMessages) trayIcon.displayMessage( message.hasAttachment() ? "New " + message.getAttachment().getType().toString().toLowerCase() + " message received" : "New message received", message.getText(), MessageType.INFO); } }