View Javadoc
1   package com.nilhcem.fakesmtp.gui.info;
2   
3   import com.nilhcem.fakesmtp.model.UIModel;
4   import com.nilhcem.fakesmtp.server.MailSaver;
5   import org.slf4j.Logger;
6   import org.slf4j.LoggerFactory;
7   
8   import javax.swing.*;
9   import java.awt.*;
10  import java.util.Observable;
11  import java.util.Observer;
12  
13  /**
14   * Label class to display the number of received emails.
15   *
16   * @author Nilhcem
17   * @since 1.0
18   */
19  public final class NbReceivedLabel implements Observer {
20  
21  	private static final Logger LOGGER = LoggerFactory.getLogger(NbReceivedLabel.class);
22  
23  	private final JLabel nbReceived = new JLabel("0");
24  
25  	/**
26  	 * Creates the label class (with a bold font).
27  	 */
28  	public NbReceivedLabel() {
29  		Font boldFont = new Font(nbReceived.getFont().getName(), Font.BOLD, nbReceived.getFont().getSize());
30  		nbReceived.setFont(boldFont);
31  	}
32  
33  	/**
34  	 * Returns the JLabel object.
35  	 *
36  	 * @return the JLabel object.
37  	 */
38  	public JLabel get() {
39  		return nbReceived;
40  	}
41  
42  	/**
43  	 * Actions which will be done when the component will be notified by an Observable object.
44  	 * <ul>
45  	 *   <li>If the observable element is a {@link MailSaver} object, the method will increment
46  	 *   the number of received messages and update the {@link UIModel};</li>
47  	 *   <li>If the observable element is a {@link ClearAllButton}, the method will reinitialize
48  	 *   the number of received messages and update the {@link UIModel};</li>
49  	 *   <li>When running on OS X the method will also update the Dock Icon with the number of
50  	 *   received messages.</li>
51  	 * </ul>
52  	 *
53  	 * @param o the observable element which will notify this class.
54  	 * @param arg optional parameters (not used).
55  	 */
56  	@Override
57  	public void update(Observable o, Object arg) {
58  		if (o instanceof MailSaver) {
59  			UIModel model = UIModel.INSTANCE;
60  			int countMsg = model.getNbMessageReceived() + 1;
61  			String countMsgStr = Integer.toString(countMsg);
62  
63  			model.setNbMessageReceived(countMsg);
64  			updateDockIconBadge(countMsgStr);
65  			nbReceived.setText(countMsgStr);
66  		} else if (o instanceof ClearAllButton) {
67  			UIModel.INSTANCE.setNbMessageReceived(0);
68  			updateDockIconBadge("");
69  			nbReceived.setText("0");
70  		}
71  	}
72  
73  	private void updateDockIconBadge(String badgeValue) {
74  		// No-op in headless or unsupported environments
75  		if (GraphicsEnvironment.isHeadless() || !Taskbar.isTaskbarSupported()) {
76  			return;
77  		}
78  
79  		Taskbar taskbar = Taskbar.getTaskbar();
80  		try {
81  			// Prefer text badges when supported; pass null to clear the badge
82  			if (taskbar.isSupported(Taskbar.Feature.ICON_BADGE_TEXT)) {
83  				taskbar.setIconBadge(badgeValue);
84  			} else if (taskbar.isSupported(Taskbar.Feature.ICON_BADGE_NUMBER)) {
85  				// Some platforms accept only numbers: pass a numeric string or null
86  				String numeric = (badgeValue != null && badgeValue.matches("\\d+")) ? badgeValue : null;
87  				taskbar.setIconBadge(numeric);
88  			}
89  		} catch (UnsupportedOperationException | SecurityException e) {
90  			LOGGER.debug("Dock badging not supported/allowed: {}", e.getMessage());
91  		} catch (Exception e) {
92  			LOGGER.error("Failed to set dock badge", e);
93  		}
94  	}
95  }