AWT SystemTray

I wanted to test the AWT SystemTray class in Java 1.6, so I changed Notifications.java. Works nice for me and it looks nicer in my opinion at least in Linux. In case someone is interested here is the diff:

Index: Notifications.java

===================================================================

— Notifications.java (revision 8210)

+++ Notifications.java (working copy)

@@ -10,8 +10,10 @@

package org.jivesoftware.spark.component;

-import org.jdesktop.jdic.tray.SystemTray;

-import org.jdesktop.jdic.tray.TrayIcon;

+import java.awt.AWTException;

+import java.awt.SystemTray;

+import java.awt.TrayIcon;

+import java.awt.event.MouseListener;

import org.jivesoftware.MainWindow;

import org.jivesoftware.MainWindowListener;

import org.jivesoftware.Spark;

@@ -56,7 +58,7 @@

  • Handles tray icon operations inside of Spark. Use to display incoming chat requests, incoming messages

  • and general notifications.

*/

-public final class Notifications implements ActionListener, MainWindowListener {

+public final class Notifications implements MouseListener, ActionListener, MainWindowListener {

private ImageIcon availableIcon;

private ImageIcon unavaliableIcon;

private ImageIcon busyIcon;

@@ -78,6 +80,8 @@

private JFrame hideWindow = null;

private long madeVisibleTime = 0;

  • private JPopupMenu popupMenu = new JPopupMenu(Res.getString(“title.tray.information”));

/**

  • Creates a new instance of notifications.

@@ -90,7 +94,7 @@

SystemTray tray = null;

try {

  •        tray = SystemTray.getDefaultSystemTray();
    
  •        tray = SystemTray.getSystemTray();
    

}

catch (Throwable e) {

Log.error(e);

@@ -101,11 +105,9 @@

availableIcon = SparkRes.getImageIcon(SparkRes.TRAY_IMAGE);

unavaliableIcon = SparkRes.getImageIcon(SparkRes.MESSAGE_AWAY);

busyIcon = SparkRes.getImageIcon(SparkRes.MESSAGE_DND);

  •    trayIcon = new TrayIcon(availableIcon);
    
  •    trayIcon = new TrayIcon(availableIcon.getImage());
    

trayIcon.setToolTip(“Spark Client”); // NORES

  •    JPopupMenu popupMenu = new JPopupMenu(Res.getString("title.tray.information"));
    

// Add DND Menus

addStatusMenuItems();

@@ -142,12 +144,17 @@

SparkManager.getMainWindow().addMainWindowListener(this);

  •    trayIcon.setPopupMenu(popupMenu);
    
  •    trayIcon.addMouseListener(this);
    

trayIcon.addActionListener(this);

if (tray != null) {

  •        tray.addTrayIcon(trayIcon);
    
  •        try {
    
  •            tray.add(trayIcon);
    
  •        } catch (AWTException ex) {
    
  •            ex.printStackTrace();
    
  •        }
    

}

SparkManager.getSessionManager().addPresenceListener(new PresenceListener() {

public void presenceChanged(Presence presence) {

changePresence(presence);

@@ -166,13 +173,13 @@

}

if (presence.getMode() == Presence.Mode.available || presence.getMode() == Presence.Mode.chat) {

  •        trayIcon.setIcon(availableIcon);
    
  •        trayIcon.setImage(availableIcon.getImage());
    

}

else if (presence.getMode() == Presence.Mode.away || presence.getMode() == Presence.Mode.xa) {

  •        trayIcon.setIcon(unavaliableIcon);
    
  •        trayIcon.setImage(unavaliableIcon.getImage());
    

}

else {

  •        trayIcon.setIcon(busyIcon);
    
  •        trayIcon.setImage(busyIcon.getImage());
    

}

// Get Status Text

@@ -364,5 +371,30 @@

// trayIcon.displayMessage(title, body, TrayIcon.INFO_MESSAGE_TYPE);

}

  • public void mouseClicked(MouseEvent e) {

  • }

  • public void mousePressed(MouseEvent e) {

  •    if (e.isPopupTrigger()) {
    
  •            popupMenu.setLocation(e.getX(), e.getY());
    
  •            popupMenu.setInvoker(popupMenu);
    
  •            popupMenu.setVisible(true);
    
  •        }
    
  • }

  • public void mouseReleased(MouseEvent e) {

  •    if (e.isPopupTrigger()) {
    
  •            popupMenu.setLocation(e.getX(), e.getY());
    
  •            popupMenu.setInvoker(popupMenu);
    
  •            popupMenu.setVisible(true);
    
  •        }
    
  • }

  • public void mouseEntered(MouseEvent e) {

  • }

  • public void mouseExited(MouseEvent e) {

  • }

}

Been trying to push for having the JDK1.6’'s Systray used instead of JDIC for so many reasons.

I really hope that it happens someday. JDIC is no fun with Linux

Yes, but I guess they don’'t want to lose compatibility with other VM versions just for this little change.

I thought about implementing both and then deciding by the version of VM which one is used.

I tried to implement it with smallest changes possible but needed to add 2 new classes and 1 new interface to the component package.

Notifications diff:

Index: Notifications.java

===================================================================

— Notifications.java (revision 8210)

+++ Notifications.java (working copy)

@@ -10,8 +10,7 @@

package org.jivesoftware.spark.component;

-import org.jdesktop.jdic.tray.SystemTray;-import org.jdesktop.jdic.tray.TrayIcon;+import java.awt.event.MouseListener;import org.jivesoftware.MainWindow;import org.jivesoftware.MainWindowListener;import org.jivesoftware.Spark;@@ -20,6 +19,7 @@

import org.jivesoftware.smack.packet.Presence;import org.jivesoftware.spark.SparkManager;import org.jivesoftware.spark.Workspace;+import org.jivesoftware.spark.component.AWTTray;import org.jivesoftware.spark.ui.PresenceListener;import org.jivesoftware.spark.ui.status.StatusBar;import org.jivesoftware.spark.ui.status.StatusItem;@@ -56,11 +56,11 @@

  • Handles tray icon operations inside of Spark. Use to display incoming chat requests, incoming messages* and general notifications.*/-public final class Notifications implements ActionListener, MainWindowListener {

+public final class Notifications implements MouseListener, ActionListener, MainWindowListener {

private ImageIcon availableIcon;

private ImageIcon unavaliableIcon;

private ImageIcon busyIcon;

  • private TrayIcon trayIcon;
  • Tray tray = null;

private JPopupMenu notificationDialog;

private WrappedLabel messageLabel = new WrappedLabel();

@@ -78,6 +78,8 @@

private JFrame hideWindow = null;

private long madeVisibleTime = 0;

  • private JPopupMenu popupMenu = new JPopupMenu(Res.getString(“title.tray.information”));

/**

  • Creates a new instance of notifications.

@@ -88,9 +90,11 @@

return;

}

  • SystemTray tray = null;try {

  • tray = SystemTray.getDefaultSystemTray();

  • if(Integer.parseInt(System.getProperty(“java.version”).substring(2, 3)) < 6)

  • tray = new JDICTray();

  • else

  • tray = new AWTTray();

}catch (Throwable e) {

Log.error(e);

@@ -101,11 +105,11 @@

availableIcon = SparkRes.getImageIcon(SparkRes.TRAY_IMAGE);

unavaliableIcon = SparkRes.getImageIcon(SparkRes.MESSAGE_AWAY);

busyIcon = SparkRes.getImageIcon(SparkRes.MESSAGE_DND);

  • trayIcon = new TrayIcon(availableIcon);

  • trayIcon.setToolTip(“Spark Client”); // NORES

  • tray.add(availableIcon);

  • tray.setTooltip(“Spark Client”);

  • JPopupMenu popupMenu = new JPopupMenu(Res.getString(“title.tray.information”));

// Add DND Menus

addStatusMenuItems();

@@ -142,12 +146,11 @@

SparkManager.getMainWindow().addMainWindowListener(this);

  • trayIcon.setPopupMenu(popupMenu);

  • trayIcon.addActionListener(this);

  • tray.setPopupMenu(popupMenu);

  • tray.addMouseListener(this);

  • tray.addActionListener(this);

  • if (tray != null) {

  • tray.addTrayIcon(trayIcon);

  • }+ SparkManager.getSessionManager().addPresenceListener(new PresenceListener() {

public void presenceChanged(Presence presence) {

changePresence(presence);

@@ -166,19 +169,19 @@

}
if (presence.getMode() == Presence.Mode.available || presence.getMode() == Presence.Mode.chat) {

  • trayIcon.setIcon(availableIcon);
  • tray.setImage(availableIcon);

}else if (presence.getMode() == Presence.Mode.away || presence.getMode() == Presence.Mode.xa) {

  • trayIcon.setIcon(unavaliableIcon);
  • tray.setImage(unavaliableIcon);

}else {

  • trayIcon.setIcon(busyIcon);
  • tray.setImage(busyIcon);

}
// Get Status Textif (presence.isAvailable()) {String status = presence.getStatus();- trayIcon.setToolTip(“Spark Client\n” + status);+ tray.setTooltip(“Spark Client\n” + status);}}
@@ -364,5 +367,30 @@
// trayIcon.displayMessage(title, body, TrayIcon.INFO_MESSAGE_TYPE);}

  • public void mouseClicked(MouseEvent e) {

  • }

  • public void mousePressed(MouseEvent e) {

  • if (e.isPopupTrigger()) {

  • popupMenu.setLocation(e.getX(), e.getY());

  • popupMenu.setInvoker(popupMenu);

  • popupMenu.setVisible(true);

  • }+ }++ public void mouseReleased(MouseEvent e) {

  • if (e.isPopupTrigger()) {

  • popupMenu.setLocation(e.getX(), e.getY());

  • popupMenu.setInvoker(popupMenu);

  • popupMenu.setVisible(true);

  • }+ }++ public void mouseEntered(MouseEvent e) {

  • }++ public void mouseExited(MouseEvent e) {

  • }++}

Interface Tray:

package org.jivesoftware.spark.component;

import java.awt.event.ActionListener;

import java.awt.event.MouseListener;

import javax.swing.ImageIcon;

import javax.swing.JPopupMenu;

public interface Tray {

abstract public void setImage(ImageIcon i);

abstract public void add(ImageIcon i);

abstract public void setTooltip(String s);

abstract public void addMouseListener(MouseListener l);

abstract public void addActionListener(ActionListener l);

abstract public void setPopupMenu(JPopupMenu m);

}

Class AWTTray:

package org.jivesoftware.spark.component;

import java.awt.AWTException;

import java.awt.Image;

import java.awt.SystemTray;

import java.awt.TrayIcon;

import java.awt.event.ActionListener;

import java.awt.event.MouseListener;

import javax.swing.ImageIcon;

import javax.swing.JPopupMenu;

public class AWTTray implements Tray{

private SystemTray tray;

private TrayIcon icon;

/** Creates a new instance of AWTTray */

public AWTTray() {

tray = SystemTray.getSystemTray();

}

public void setImage(ImageIcon i) {

icon = new TrayIcon(i.getImage());

}

public void add(ImageIcon i) {

icon = new TrayIcon(i.getImage());

try {

tray.add(icon);

} catch (AWTException ex) {

ex.printStackTrace();

}
}

public void setTooltip(String s) {

icon.setToolTip(s);

}

public void addMouseListener(MouseListener l) {

icon.addMouseListener(l);

}

public void addActionListener(ActionListener l) {

icon.addActionListener(l);

}

public void setPopupMenu(JPopupMenu m) {

}

}

Class JDICTray:

package org.jivesoftware.spark.component;

import java.awt.event.ActionListener;

import java.awt.event.MouseListener;

import javax.swing.ImageIcon;

import javax.swing.JPopupMenu;

import org.jdesktop.jdic.tray.SystemTray;

import org.jdesktop.jdic.tray.TrayIcon;

public class JDICTray implements Tray {

private SystemTray tray;

private TrayIcon icon;

/** Creates a new instance of JDICTray */

public JDICTray() {

tray = SystemTray.getDefaultSystemTray();

}

public void setImage(ImageIcon i) {

icon.setIcon(i);

}

public void add(ImageIcon i) {

icon = new TrayIcon(i);

tray.addTrayIcon(icon);

}

public void setTooltip(String s) {

icon.setToolTip(s);

}

public void addMouseListener(MouseListener l) {

}

public void addActionListener(ActionListener l) {

icon.addActionListener(l);

}

public void setPopupMenu(JPopupMenu m) {

icon.setPopupMenu(m);

}

}

Message was edited by: tezem