View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2009  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  package davmail.ui.tray;
20  
21  import davmail.BundleMessage;
22  import davmail.DavGateway;
23  import davmail.Settings;
24  import davmail.ui.AboutFrame;
25  import davmail.ui.SettingsFrame;
26  import org.apache.log4j.Level;
27  
28  import javax.swing.*;
29  import java.awt.*;
30  import java.awt.event.ActionListener;
31  import java.awt.image.BufferedImage;
32  import java.util.ArrayList;
33  
34  /**
35   * Tray icon handler based on java 1.6
36   */
37  public class AwtGatewayTray implements DavGatewayTrayInterface {
38      protected static final String TRAY_PNG = "tray.png";
39  
40      protected static final String TRAY_ACTIVE_PNG = "tray2.png";
41      protected static final String TRAY_INACTIVE_PNG = "trayinactive.png";
42  
43      protected static final String TRAY128_PNG = "tray128.png";
44      protected static final String TRAY128_ACTIVE_PNG = "tray128active.png";
45      protected static final String TRAY128_INACTIVE_PNG = "tray128inactive.png";
46  
47      protected AwtGatewayTray() {
48      }
49  
50      static AboutFrame aboutFrame;
51      static SettingsFrame settingsFrame;
52      ActionListener settingsListener;
53  
54      static TrayIcon trayIcon;
55      protected static ArrayList<Image> frameIcons;
56      protected static BufferedImage image;
57      protected static BufferedImage activeImage;
58      protected static BufferedImage inactiveImage;
59  
60      private boolean isActive = true;
61  
62      /**
63       * Return AWT Image icon for frame title.
64       *
65       * @return frame icon
66       */
67      @Override
68      public java.util.List<Image> getFrameIcons() {
69          return frameIcons;
70      }
71  
72      /**
73       * Switch tray icon between active and standby icon.
74       */
75      public void switchIcon() {
76          isActive = true;
77          SwingUtilities.invokeLater(() -> {
78              if (trayIcon.getImage().equals(image)) {
79                  trayIcon.setImage(activeImage);
80              } else {
81                  trayIcon.setImage(image);
82              }
83          });
84      }
85  
86      /**
87       * Set tray icon to inactive (network down)
88       */
89      public void resetIcon() {
90          SwingUtilities.invokeLater(() -> trayIcon.setImage(image));
91      }
92  
93      /**
94       * Set tray icon to inactive (network down)
95       */
96      public void inactiveIcon() {
97          isActive = false;
98          SwingUtilities.invokeLater(() -> trayIcon.setImage(inactiveImage));
99      }
100 
101     /**
102      * Check if current tray status is inactive (network down).
103      *
104      * @return true if inactive
105      */
106     public boolean isActive() {
107         return isActive;
108     }
109 
110     /**
111      * Display balloon message for log level.
112      *
113      * @param message text message
114      * @param level   log level
115      */
116     public void displayMessage(final String message, final Level level) {
117         SwingUtilities.invokeLater(() -> {
118             if (trayIcon != null) {
119                 TrayIcon.MessageType messageType = null;
120                 if (level.equals(Level.INFO)) {
121                     messageType = TrayIcon.MessageType.INFO;
122                 } else if (level.equals(Level.WARN)) {
123                     messageType = TrayIcon.MessageType.WARNING;
124                 } else if (level.equals(Level.ERROR)) {
125                     messageType = TrayIcon.MessageType.ERROR;
126                 }
127                 if (messageType != null) {
128                     trayIcon.displayMessage(BundleMessage.format("UI_DAVMAIL_GATEWAY"), message, messageType);
129                 }
130                 trayIcon.setToolTip(BundleMessage.format("UI_DAVMAIL_GATEWAY") + '\n' + message);
131             }
132         });
133     }
134 
135     /**
136      * Open about window
137      */
138     public void about() {
139         SwingUtilities.invokeLater(() -> {
140             aboutFrame.update();
141             aboutFrame.setVisible(true);
142             aboutFrame.toFront();
143             aboutFrame.requestFocus();
144         });
145     }
146 
147     /**
148      * Open settings window
149      */
150     public void preferences() {
151         SwingUtilities.invokeLater(() -> {
152             settingsFrame.reload();
153             settingsFrame.setVisible(true);
154             settingsFrame.toFront();
155             settingsFrame.repaint();
156             settingsFrame.requestFocus();
157         });
158     }
159 
160     /**
161      * Create tray icon and register frame listeners.
162      */
163     public void init() {
164         SwingUtilities.invokeLater(this::createAndShowGUI);
165     }
166 
167     public void dispose() {
168         SystemTray.getSystemTray().remove(trayIcon);
169 
170         // dispose frames
171         settingsFrame.dispose();
172         aboutFrame.dispose();
173     }
174 
175     protected void loadIcons() {
176         image = DavGatewayTray.adjustTrayIcon(DavGatewayTray.loadImage(AwtGatewayTray.TRAY_PNG));
177         activeImage = DavGatewayTray.adjustTrayIcon(DavGatewayTray.loadImage(AwtGatewayTray.TRAY_ACTIVE_PNG));
178         inactiveImage = DavGatewayTray.adjustTrayIcon(DavGatewayTray.loadImage(AwtGatewayTray.TRAY_INACTIVE_PNG));
179 
180         frameIcons = new ArrayList<>();
181         frameIcons.add(DavGatewayTray.loadImage(AwtGatewayTray.TRAY128_PNG));
182         frameIcons.add(DavGatewayTray.loadImage(AwtGatewayTray.TRAY_PNG));
183     }
184 
185     protected void createAndShowGUI() {
186         System.setProperty("swing.defaultlaf", UIManager.getSystemLookAndFeelClassName());
187 
188         // get the SystemTray instance
189         SystemTray tray = SystemTray.getSystemTray();
190         loadIcons();
191 
192         // create a popup menu
193         PopupMenu popup = new PopupMenu();
194 
195         aboutFrame = new AboutFrame();
196         // create an action settingsListener to listen for settings action executed on the tray icon
197         ActionListener aboutListener = e -> about();
198         // create menu item for the default action
199         MenuItem aboutItem = new MenuItem(BundleMessage.format("UI_ABOUT"));
200         aboutItem.addActionListener(aboutListener);
201         popup.add(aboutItem);
202 
203         settingsFrame = new SettingsFrame();
204         // create an action settingsListener to listen for settings action executed on the tray icon
205         settingsListener = e -> preferences();
206         // create menu item for the default action
207         MenuItem defaultItem = new MenuItem(BundleMessage.format("UI_SETTINGS"));
208         defaultItem.addActionListener(settingsListener);
209         popup.add(defaultItem);
210 
211 
212         // create an action exitListener to listen for exit action executed on the tray icon
213         ActionListener exitListener = e -> {
214             try {
215                 DavGateway.stop();
216             } catch (Exception exc) {
217                 DavGatewayTray.error(exc);
218             }
219             // make sure we do exit
220             System.exit(0);
221         };
222         // create menu item for the exit action
223         MenuItem exitItem = new MenuItem(BundleMessage.format("UI_EXIT"));
224         exitItem.addActionListener(exitListener);
225         popup.add(exitItem);
226 
227         /// ... add other items
228         // construct a TrayIcon
229         trayIcon = new TrayIcon(image, BundleMessage.format("UI_DAVMAIL_GATEWAY"), popup);
230         // set the TrayIcon properties
231         trayIcon.addActionListener(settingsListener);
232         // ...
233         // add the tray image
234         try {
235             tray.add(trayIcon);
236         } catch (AWTException e) {
237             DavGatewayTray.warn(new BundleMessage("LOG_UNABLE_TO_CREATE_TRAY"), e);
238         }
239 
240         // display settings frame on first start
241         if (Settings.isFirstStart()) {
242             settingsFrame.setVisible(true);
243             settingsFrame.toFront();
244             settingsFrame.repaint();
245             settingsFrame.requestFocus();
246         }
247     }
248 
249 }