All Downloads are FREE. Search and download functionalities are using the official Maven repository.

es.ree.eemws.kit.folders.StatusIcon Maven / Gradle / Ivy

Go to download

Client implementation of IEC 62325-504 technical specification. eemws-kit includes command line utilities to invoke the eem web services, as well as several GUI applications (browser, editor, ...)

The newest version!
/*
 * Copyright 2024 Redeia.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 *  by the Free Software Foundation, version 3 of the license.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTIBIILTY or FITNESS FOR A PARTICULAR PURPOSE. See GNU Lesser General
 * Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program. If not, see
 * http://www.gnu.org/licenses/.
 *
 * Any redistribution and/or modification of this program has to make
 * reference to Redeia as the copyright owner of the program.
 */

package es.ree.eemws.kit.folders;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.MenuShortcut;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;

import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

/**
 * Status Icon, changes the imagen when the application is processing messages.
 * Handles a basic menu to exit the application. Not available in all the
 * platforms.
 *
 * @author Redeia.
 * @version 2.1 01/01/2024
 *
 */
public final class StatusIcon {

	/**
	 * System property key. If set, the application is in "interactive" mode and
	 * will display a Windows icon.
	 */
	private static final String WINDOWS_SYSTEM_INTERACTIVE = "interactive"; //$NON-NLS-1$

	/** Path to image that notifies "normal" status. */
	private static final String IMAGE_IDLE = "/images/idle.gif"; //$NON-NLS-1$

	/** Path to image that notifies "busy" status. */
	private static final String IMAGE_BUSY = "/images/busy.gif"; //$NON-NLS-1$

	/** Idle message. */
	private static final String MSG_IDLE = MessageCatalog.MF_STATUS_IDLE.getMessage();

	/** Busy message. */
	private static final String MSG_BUSY = MessageCatalog.MF_STATUS_BUSY.getMessage();

	/** Task bar icon on notification area. */
	private TrayIcon trayIcon = null;

	/** Magic folder instance identification. */
	private String identification = null;

	/** Path to image displayed when no tasks are being performed. */
	private Image imgIdle;

	/** Path to image displayed when files are being processed. */
	private Image imageBusy;

	/**
	 * Number of invocations to the setBusy method. Avoids to show the
	 * icon as "idle" if two threads invokes the "busy" method and then one of them
	 * calls the "idle" method and there is still one thread busy. Idle = 0
	 */
	private static Integer numBusy = 0;

	/** Single instance of the class (singleton) */
	private static final StatusIcon SINGLE_STATUS = new StatusIcon();

	/**
	 * Initializes the class.
	 */
	private StatusIcon() {

		if (isInteractive() && SystemTray.isSupported()) {

			imgIdle = Toolkit.getDefaultToolkit().getImage(getClass().getResource(IMAGE_IDLE));
			imageBusy = Toolkit.getDefaultToolkit().getImage(getClass().getResource(IMAGE_BUSY));

			var exitItem = new MenuItem(MessageCatalog.MF_MENU_ITEM_EXIT.getMessage());
			exitItem.setShortcut(new MenuShortcut(MessageCatalog.MF_MENU_ITEM_EXIT_HOT_KEY.getChar()));
			exitItem.addActionListener(arg0 -> exit());
			var iconMenu = new PopupMenu();
			iconMenu.add(exitItem);

			trayIcon = new TrayIcon(imgIdle, MSG_IDLE, iconMenu);

			trayIcon.setImageAutoSize(true);
			try {
				var tray = SystemTray.getSystemTray();
				tray.add(trayIcon);
			} catch (AWTException e) {
				trayIcon = null;
			}
		}
	}

	/**
	 * Get the only instance of the StatusIcon class.
	 *
	 * @return A StatusIcon class.
	 */
	public static StatusIcon getStatus() {
		return SINGLE_STATUS;
	}

	/**
	 * Sets this MF identification. Will be shown in the system tray.
	 *
	 * @param id This MF instance identification.
	 */
	public void setIdentification(final String id) {
		identification = id;
	}

	/**
	 * Removes the icon from the system tray.
	 */
	public void removeIcon() {
		if (trayIcon != null) {
			SystemTray.getSystemTray().remove(trayIcon);
		}
	}

	/**
	 * Checks if the system key that set up the instance as interactive (not
	 * service) is set.
	 *
	 * @return true if the application is running in interactive mode.
	 *         false if running in daemon mode (without gui)
	 */
	public boolean isInteractive() {
		return System.getProperty(WINDOWS_SYSTEM_INTERACTIVE) != null;
	}

	/**
	 * Activate the the icon notifying the "Busy" status on notification area.
	 */
	public synchronized void setBusy() {
		if (trayIcon != null) {
			numBusy++;
			if (identification == null) {
				trayIcon.setToolTip(MSG_BUSY);
			} else {
				trayIcon.setToolTip(MSG_BUSY + " (" + identification + ")"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			trayIcon.setImage(imageBusy);
		}
	}

	/**
	 * Activate the the icon notifying the "Idle" status on notification area.
	 */
	public synchronized void setIdle() {
		if (trayIcon != null) {
			numBusy--;
			if (numBusy < 0) {
				numBusy = 0;
			}
			if (numBusy == 0) {
				if (identification == null) {
					trayIcon.setToolTip(MSG_IDLE);
				} else {
					trayIcon.setToolTip(MSG_IDLE + " (" + identification + ")"); //$NON-NLS-1$ //$NON-NLS-2$
				}
				trayIcon.setImage(imgIdle);
			}
		}
	}

	/**
	 * Ask for confirmation to exit the application.
	 */
	private void exit() {

		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException | InstantiationException | IllegalAccessException
		        | UnsupportedLookAndFeelException e) {

			// Ignore the exception, go ahead with the current UI..
		}

		int answer;
		if (identification == null) {
			answer = JOptionPane.showConfirmDialog(null, MessageCatalog.MF_EXIT_APPLICATION.getMessage(),
			        MessageCatalog.MF_EXIT_APPLICATION_TITLE.getMessage(), JOptionPane.OK_CANCEL_OPTION,
			        JOptionPane.QUESTION_MESSAGE);
		} else {
			answer = JOptionPane.showConfirmDialog(null, MessageCatalog.MF_EXIT_APPLICATION.getMessage(),
			        MessageCatalog.MF_EXIT_APPLICATION_TITLE.getMessage() + " (" + identification + ")",
			        JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
		}

		if (answer == JOptionPane.OK_OPTION) {
			System.exit(0); // NOSONAR We want to force application to exit.
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy