package fr.jcgay.notification.notifier.systemtray; import com.google.common.base.MoreObjects; import com.google.common.base.Objects; import fr.jcgay.notification.Application; import fr.jcgay.notification.DiscoverableNotifier; import fr.jcgay.notification.Notification; import fr.jcgay.notification.Notifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.awt.*; import java.awt.TrayIcon.MessageType; import static java.util.concurrent.TimeUnit.SECONDS; public class SystemTrayNotifier implements DiscoverableNotifier { private static final Logger LOGGER = LoggerFactory.getLogger(SystemTrayNotifier.class); private final Application application; private boolean skipNotifications; private TrayIcon icon; public SystemTrayNotifier(Application application) { LOGGER.debug("Configuring System Tray for application {}.", application); this.application = application; } @Override public Notifier init() { if (icon != null) { return this; } if (!SystemTray.isSupported()) { skipNotifications = true; LOGGER.warn("SystemTray is not supported, skipping notifications..."); return this; } icon = new TrayIcon(createImage(application.icon().toByteArray()), application.name()); icon.setImageAutoSize(true); try { SystemTray.getSystemTray().add(icon); } catch (AWTException e) { throw new SystemTrayNotificationException("Error initializing SystemTray Icon.", e); } return this; } @Override public void send(Notification notification) { if (!skipNotifications) { icon.setImage(createImage(notification.icon().toByteArray())); icon.displayMessage(notification.title(), notification.message(), toMessageType(notification.level())); } } @Override public void close() { if (!skipNotifications) { try { Thread.sleep(application.timeout() == -1 ? SECONDS.toMillis(2) : application.timeout()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } SystemTray.getSystemTray().remove(icon); } } @Override public boolean isPersistent() { return true; } @Override public boolean tryInit() { init(); return !skipNotifications; } private static MessageType toMessageType(Notification.Level level) { switch (level) { case INFO: return MessageType.INFO; case WARNING: return MessageType.WARNING; case ERROR: return MessageType.ERROR; default: return MessageType.NONE; } } private Image createImage(byte[] imageData) { return Toolkit.getDefaultToolkit().createImage(imageData); } @Override public int hashCode() { return Objects.hashCode(application); } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null || getClass() != obj.getClass()) { return false; } final SystemTrayNotifier other = (SystemTrayNotifier) obj; return Objects.equal(this.application, other.application); } @Override public String toString() { return MoreObjects.toStringHelper(this) .add("application", application) .toString(); } }