static TrayIcon installTrayIcon(S imageID, S tooltip) { ret installTrayIcon(imageID, tooltip, null); } // menuItems can also just be a PopupMenu // also, first of menuItems can be a Runnable for left-click on icon static TrayIcon installTrayIcon(S imageID, S tooltip, O... menuItems) ctex { // convenience parameter swap :-) if (!isSnippetID(imageID) && isSnippetID(tooltip)) { S s = tooltip; tooltip = imageID; imageID = s; } ret installTrayIcon(imageIcon(imageID).getImage(), tooltip, menuItems); } static TrayIcon installTrayIcon(final Image image, fS tooltip, fO... _menuItems) ctex { ret swing(func -> TrayIcon { Runnable leftClick = null; O[] menuItems = _menuItems; if (l(menuItems) > 0 && menuItems[0] instanceof Runnable) { leftClick = (Runnable) menuItems[0]; menuItems = dropFirst(menuItems); } PopupMenu menu = makePopupMenu(menuItems); TrayIcon trayIcon = new TrayIcon(image, tooltip, menu); trayIcon.setImageAutoSize(true); if (leftClick != null) { final Runnable _leftClick = leftClick; onLeftClick(trayIcon, _leftClick); } SystemTray.getSystemTray().add(trayIcon); ret trayIcon; }); }